Direct solvers
|
Seldon is interfaced with libraries performing the direct solution of very large sparse linear systems : MUMPS, SuperLU, SuiteSparse, Pastix, Wsmp and Pardiso (as included in MKL). An example file is located in test/program/direct_test.cpp. An example file with parallel direct solver is present in test/unit/distributed_solver.cc. To compile Seldon with external direct solvers, we advise to use the Makefile provided (Makefile.LINUX).
If you want to test the interface with MUMPS (tested with release 5.4), assuming that MUMPS has been compiled in directory MumpsDir
(sequential), Metis-5.1 installed in directory MetisDir
, and Scotch in directory ScotchDir
, you can compile this file by using the makefile and set USE_MUMPS = YES. If you want to compile manually this file, you can type :
g++ -DSELDON_WITH_MUMPS test/program/direct_test.cpp -I. -IMumpsDir/include -IMumpsDir/libseq -LMumpsDir/lib -ldmumps -lzmumps -lmumps_common -lpord \ -LMumpsDir/libseq -lmpiseq -LMetisDir -lmetis -lm -lpthread -llapack -lblas -lgfortran
You can simplify the last command, if you didn't install Metis and didn't compile MUMPS with this library. To compile Mumps in sequential with Metis, you can copy Make.inc/Makefile.inc.generic.SEQ into Makefile.inc, and modify the two lines
IMETIS = -IMetisDir/include ORDERINGSF = -Dpord -Dmetis
before compiling Mumps. To use Seldon with Mumps in parallel compilation, the command line would be :
mpicxx -DSELDON_WITH_MUMPS -DSELDON_WITH_MPI test/program/direct_test.cpp -I. IMumpsDir/include \ -LMumpsDir/lib -ldmumps -lzmumps -lmumps_common -lpord -lscalapack -lblacs -LScotchDir/lib -lesmumps -lscotch -lscotcherr -LMetisDir -lmetis -llapack -lblas -lgfortran -lm -lpthread -lmpi_mpifh
If you have compiled Mumps with ParMetis and PtScotch, the compilation will be performed by typing:
mpicxx -DSELDON_WITH_MUMPS -DSELDON_WITH_MPI test/program/direct_test.cpp -I. -IMumpsDir/include \ -LMumpsDir/lib -ldmumps -lzmumps -lmumps_common -lpord \ -lscalapack -lblacs -LScotchDir/lib -lesmumps -lscotch -lscotcherr \ -lptesmumps -lptscotch -lptscotcherr -LParMetisDir/lib -lparmetis \ -LMetisDir -lmetis -llapack -lblas -lgfortran -lm -lpthread -lmpi_mpifh
The last library (-lmpi_mpifh) depends on the MPI library installed on the machine. It can -lmpi_f77 or -lmpi_fort. When compiling Mumps in parallel, you can start from the Make.inc/Makefile.inc.generic and modify the following lines
SCOTCHDIR = ${HOME}/Solve/scotch_6.0.4 ISCOTCH = -I/include IMETIS = -I${HOME}/Solve/metis-5.1.0/include -I${HOME}/Solve/parmetis-4.0.3/include ORDERINGSF = -Dscotch -Dmetis -Dpord -Dptscotch -Dparmetis
for a compilation with Metis, ParMetis, Scotch and PtScotch. For the installation of Scotch, you can check the file "INSTALL.txt" and the documentation provided with the library. We remind you the main steps for the installation of this library :
For the installation of Metis (and ParMetis in parallel), you can read the documentation of Metis, or follow these basic instructions
For ParMetis (version 4.0.3), the procedure is similar with a make config followed by a make.
The libraries UmfPack and Cholmod are part of SuiteSparse (tested with release 5-10.0). You can compile with the makefile by setting USE_UMFPACK:=YES and/or USE_CHOLDMOD:=YES. If SuiteDir
denotes the directory where SuiteSparse has been installed and MetisDir
the directory where Metis has been installed, you can compile manually by typing :
g++ -I. -DSELDON_WITH_UMFPACK -DSELDON_WITH_CHOLMOD test/program/direct_test.cpp -ISuiteDir/SuiteSparse_config -ISuiteDir/AMD/Include -ISuiteDir/CAMD/Include -ISuiteDir/UMFPACK/Include \ -ISuiteDir/CHOLMOD/Include -ISuiteDir/COLAMD/Include -ISuiteDir/CCOLAMD/Include \ -LSuiteDir/UMFPACK/Lib -lumfpack -LSuiteDir/CHOLMOD/Lib -lcholmod -LSuiteDir/AMD/Lib -lamd \ -LSuiteDir/CAMD/Lib -lcamd -LSuiteDir/COLAMD/Lib -lcolamd -LSuiteDir/CCOLAMD/Lib -lccolamd -LMetisDir -lmetis \ -LSuiteDir/SuiteSparse_config -lsuitesparseconfig -llapack -lblas -fopenmp -lgfortran
Cholmod performs only Cholesky factorisation, but with that library, it is possible to compute a matrix-vector product L x or LT x, where A = L LT, and solves L y = x or LT y = x. For the installation of SuiteSparse, you can look at the documentation or follow these basic instructions :
Seldon is interfaced by default with UmfPack that uses 32-bits integers. If you have compiled UmfPack with 64-bits integers, you need to set the flag UMFPACK_INTSIZE64 before including Seldon.
For SuperLU (tested with release 5.2.2), you can compile it with the makefile and USE_SUPERLU := YES. If you want to compile direct_test.cpp manually, the compilation line reads (SuperLUdir
is the directory where SuperLU is located) :
g++ -I. -DSELDON_WITH_SUPERLU test/program/direct_test.cpp -ISuperLUdir/SRC -LSuperLUdir -lsuperlu -lblas -lgfortran
For the installation of SuperLU, you should read the documentation or complete the following instructions
Seldon is interfaced by default with SuperLU that uses 32-bits integers. If you have compiled SuperLU with 64-bits integers, you need to set the flag SUPERLU_INTSIZE64 before including Seldon. If you want to use the multi-threaded version of SuperLU, you have to compile by adding the flag SELDON_WITH_SUPERLU_MT. If you want to use the parallel version of SuperLU (tested with release 7.0.0), you have to compile with the flag SELDON_WITH_SUPERLU_DIST (both flags cannot be defined), as follows:
mpicxx -I. -DSELDON_WITH_SUPERLU_DIST -DSELDON_WITH_SUPERLU -DSELDON_WITH_MPI test/program/direct_test.cpp \ -ISuperLUdir/SRC -LSuperLUdir/lib -lsuperlu_dist_4.1 -lblas -LParmetisDir -lparmetis -LMetisDir -lmetis -lgfortran -fopenmp -lpthread
The interface with Pastix can only be compiled in parallel (tested with release 6.2.0). When compiling PastiX, you can select usual integers (32 bits) or long integers (64 bits). You can compile the file direct_test.cpp by using the makefile and USE_PASTIX := YES. If you want to compile the file manuallya, the compilation line reads (PastiXdir
is the directory where PastiX has been installed) :
mpicxx -I. -DSELDON_WITH_PASTIX -DSELDON_WITH_MPI test/program/direct_test.cpp -IPastiXdir/include \ -LPastiXdir/lib -lpastix -lspm -lpastix_kernels -LMetisDir -lmetis -LScotchDir -lscotch -lscotcherr -lptscotch -lptscotcherr \ -lhwloc -lpthread -lrt -llapacke -llapack -lblas
For the installation of Pastix, you can look at the documentation or follow these instructions :
The interface with Pardiso is written for the version contained in the MKL (Math Kernel Library). The compilation with the Makefile is completed by setting USE_PARDISO := YES. To compile manually you can type
g++ -I. -DSELDON_WITH_PARDISO test/program/direct_test.cpp -L/opt/intel/mkl/lib/ia32 -lmkl_gf -lmkl_gnu_thread -lmkl_core -fopenmp
With this command, the multi-threaded MKL is used. It will launch threads when the solver is called. If you wish to disable threads, you can link your code with the sequential library as follows:
g++ -I. -DSELDON_WITH_PARDISO test/program/direct_test.cpp -L/opt/intel/mkl/lib/ia32 -lmkl_gf -lmkl_sequential -lmkl_core
If the flag PARDISO_INTSIZE64 has been defined, pardiso will be executed with 64-bits integers. All in all, MUMPS seems more efficient and robust, and includes more functionalities than the other libraries.
The syntax of all direct solvers is similar
void GetLU(Matrix&, MatrixMumps&); void SolveLU(MatrixMumps&, Vector&);
The interface has been done only for double precision (real or complex numbers), since single precision is not accurate enough when very large sparse linear systems are solved.
We provide an example of direct solution using SuperLU.
// first we construct a sparse matrix int n = 1000; // size of linear system // we assume that you know how to fill arrays values, ptr, ind Matrix<double, General, RowSparse> A(n, n, nnz, values, ptr, ind); // then we declare vectors Vector<double> b(n), x(n); // you fill right-hand side b.Fill(); // you perform the factorization (real matrix) MatrixSuperLU<double> mat_lu; GetLU(A, mat_lu); // then you can solve as many linear systems as you want x = b; SolveLU(mat_lu, x);
If you are hesitating about which direct solver to use, or if you prefer to choose the direct solver in an input file for example, a class SparseDirectSolver has been implemented for LU and LDLT solver, and SparseCholeskySolver for Cholesky solver. This class regroups all the direct solvers interfaced by Seldon, it provides also a default sparse solver (but slow). Here an example how to use this class :
// first we construct a sparse matrix int n = 1000; // size of linear system // we assume that you know how to fill arrays values, ptr, ind Matrix<double, General, RowSparse> A(n, n, nnz, values, ptr, ind); // declaring the sparse solver // this solver will try to use in order of preference // Pastix, then Mumps, then UmfPack, then SuperLU // if finally the default sparse solver if none of the previous // libraries were available SparseDirectSolver<double> mat_lu; // displaying messages if you want mat_lu.ShowMessages(); // completing factorization of linear system mat_lu.Factorize(A); // then we declare vectors Vector<double> b(n), x(n); // you fill right-hand side b.Fill(); // then you can solve as many linear systems as you want x = b; mat_lu.Solve(x); // you can also force a direct solver : mat_lu.SelectDirectSolver(mat_lu.SUPERLU); // and an ordering mat_lu.SelectMatrixOrdering(SparseMatrixOrdering::SCOTCH);
A class SparseDistributedSolver has been written to handle both sequential matrices and parallel matrices. It derives from the class SparseDirectSolver and it can be used as follows:
Matrix<double, General, ArrayRowSparse> A(n, n); // you fill the matrix A // an object storing the factorization of A is created SparseDistributedSolver<double> mat_lu; // the matrix is factorized mat_lu.Factorize(A); // then you can solve any system (the right hand side is overwritten by the solution) Vector<double> x(n); mat_lu.Solve(x); // you can also solve the transpose system mat_lu.Solve(SeldonTrans, x); // for multiple right hand sides, it is better to provide a matrix // each column is a different right hand side Matrix<double, General, ColMajor> b; mat_lu.Solve(b); // for distributed matrices, the methods Factorize and Solve are available // and will perform the factorization over the processors sharing the matrix DistributedMatrix<double, General, ArrayRowSparse> B(n, n); mat_lu.Factorize(B); mat_lu.Solve(x);
A class DistributedCholeskySolver has been written to handle both sequential and parallel matrices (Cholesky factorization). It derives from the class SparseCholeskySolver. It can be used as follows:
Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you fill the matrix A // an object storing the factorization of A is created DistributedCholeskySolver<double> mat_lu; // the matrix is factorized mat_lu.Factorize(A); // then you can solve any system L x = b or L^T x = b // the right hand side is overwritten by the solution (A = L L^T) Vector<double> x(n); mat_lu.Solve(SeldonNoTrans, x); // you can also solve the transpose system mat_lu.Solve(SeldonTrans, x); // you can also multiply with L or L^T mat_lu.Mlt(SeldonTrans, x); // for distributed matrices, the methods Factorize and Solve are available // and will perform the factorization over the processors sharing the matrix DistributedMatrix<double, General, ArrayRowSparse> B(n, n); mat_lu.Factorize(B); mat_lu.Solve(SeldonNoTrans, x);
HideMessages | Hides all messages of the direct solver |
ShowMessages | Shows a reasonable amount of the messages of the direct solver |
ShowFullHistory | Shows all the messages that the direct solver can display |
GetN | Returns the number of columns of the factorized linear system |
GetM | Returns the number of rows of the factorized linear system |
GetTypeOrdering | Returns the ordering to use when the matrix will be reordered |
SelectOrdering | Sets the ordering to use when the matrix will be reordered |
SetPermutation | Provides manually the permutation array used to reorder the matrix |
SelectDirectSolver | Sets the direct solver to use (e.g. Mumps, Pastix, SuperLU) |
GetDirectSolver | Returns the direct solver that will be used during the factorization |
Factorize | Performs the factorization of a sparse matrix |
Solve | Solves A x = b or AT x = b, assuming that Factorize has been called |
Clear | Releases memory used by factorization |
GetMemorySize | Returns the memory used by the object in bytes |
SetPivotThreshold | Sets the threshold used for pivoting |
GetNumberOfThreadPerNode | Returns the number of threads per node (relevant for Pastix only) |
SetNumberOfThreadPerNode | Sets the number of threads per node (relevant for Pastix only) |
SetNonSymmetricIlut | Selects non-symmetric incomplete factorization |
GetThresholdMatrix | Returns the threshold used to drop values in ILUT |
SetThresholdMatrix | Sets the threshold used to drop values in ILUT |
RefineSolution | Refines the solution when calling solve |
DoNotRefineSolution | Does not refine the solution when calling solve |
SetCoefficientEstimationNeededMemory | Sets the safety coefficient used to allocate needed memory the first time |
SetMaximumCoefficientEstimationNeededMemory | Sets the maximal safety coefficient used to allocate needed memory |
SetIncreaseCoefficientEstimationNeededMemory | Sets the multiplication factor to increase the safety coefficient used to allocate needed memory |
IsAvailableSolver | Returns true if the given solver is available |
GetInfoFactorization | Returns an error code associated with the factorisation (0 if successful) |
PerformAnalysis | Performs the symbolic factorization of a matrix |
PerformFactorization | Performs the numerical factorization of a matrix, assuming that PerformAnalysis has been called |
FactorizeDistributed | Performs the factorization of a distributed matrix (parallel execution) |
PerformAnalysisDistributed | Performs the analysis of a distributed matrix (parallel execution) |
PerformFactorizationDistributed | Performs the factorization of a distributed matrix (parallel execution), assuming that PerformAnalysisDistributed has been called |
SolveDistributed | Solves A x = b or AT x = b, assuming that FactorizeDistributed has been called |
HideMessages | Hides all messages of the direct solver |
ShowMessages | Shows a reasonable amount of the messages of the direct solver |
ShowFullHistory | Shows all the messages that the direct solver can display |
GetN | Returns the number of columns of the factorized linear system |
GetM | Returns the number of rows of the factorized linear system |
GetTypeOrdering | Returns the ordering to use when the matrix will be reordered |
SelectOrdering | Sets the ordering to use when the matrix will be reordered |
SetPermutation | Provides manually the permutation array used to reorder the matrix |
SelectDirectSolver | Sets the direct solver to use (e.g. Cholmod, Pastix) |
GetDirectSolver | Returns the direct solver that will be used during the factorization |
Factorize | Performs the factorization of a sparse matrix |
Solve | Solves L x = b or LT x = b, assuming that Factorize has been called |
Clear | Releases memory used by factorization |
GetMemorySize | Returns the memory used by the object in bytes |
Mlt | computation of y = LT x or y = L x for Cholesky solver |
SetPrintLevel | Modifies the level of verbosity |
Factorize | Factorize a sequential matrix or a distributed matrix |
PerformAnalysis | Performs the symbolic factorization of a matrix (distributed or not) |
PerformFactorization | Performs the numerical factorization of a matrix (distributed or not) |
Solve | Solves a linear system assuming that Factorize has been called |
TransSolve | Solves a transpose linear system assuming that Factorize has been called |
GetSchurComplement | Computes the Schur complement |
Factorize | Factorize a sequential matrix or a distributed matrix |
Solve | Solves L x = b or LT x = b assuming that Factorize has been called |
Mlt | computation of y = LT x or y = L x for Cholesky solver |
SetPivotThreshold | Sets the threshold used for pivoting |
RefineSolution | Refines the solution when calling solve |
DoNotRefineSolution | Does not refine the solution when calling solve |
SetCoefficientEstimationNeededMemory | Sets the safety coefficient used to allocate needed memory the first time |
SetMaximumCoefficientEstimationNeededMemory | Sets the maximal safety coefficient used to allocate needed memory |
SetIncreaseCoefficientEstimationNeededMemory | Sets the multiplication factor to increase the safety coefficient used to allocate needed memory |
SetNumberOfThreadPerNode | Sets the number of threads per node |
Clear | Releases memory used by factorization |
SelectOrdering | Sets the ordering to use during factorization |
SelectParallelOrdering | Sets the ordering to use during distributed factorization |
SetPermutation | Provides manually the permutation array to use when reordering the matrix |
HideMessages | Hides messages of direct solver |
ShowMessages | Shows messages of direct solver |
ShowFullHistory | Shows all possible messages of direct solver |
GetMemorySize | returns the memory used by the solver in bytes |
GetInfoFactorization | returns the error code generated by the factorization |
FactorizeDistributed | Performs the factorization of a distributed matrix (parallel execution) |
PerformAnalysisDistributed | Performs the analysis of a distributed matrix (parallel execution) |
PerformFactorizationDistributed | Performs the factorization of a distributed matrix (parallel execution), assuming that PerformAnalysisDistributed has been called |
UseInteger8 | returns true if the solver is using 64-bits integers (integer*8 in Fortran) |
EnableOutOfCore | Enables out-of-core computations |
DisableOutOfCore | Disable out-of-core computations |
FindOrdering | computes a new ordering of rows and columns |
FactorizeMatrix | Factorizes a matrix using Mumps |
Solve | Solves A x = b using factorization computed by Mumps |
PerformAnalysis | Performs an analysis of linear system to factorize |
PerformFactorization | Performs a factorization of linear system, assuming that PerformAnalysis has been called |
GetSchurMatrix | forms Schur complement |
FactorizeMatrix | Factorizes a matrix using Pardiso |
Solve | Solves A x = b using factorization computed by Pardiso |
SetCholeskyFacto | selects a Cholesky factorisation to be performed |
FindOrdering | computes a new ordering of rows and columns |
FactorizeMatrix | Factorizes a matrix using Pastix |
Solve | Solves A x = b using factorization computed by Pastix |
Mlt | computes y = L x or y = LT x |
GetRowPermutation | returns the permutation used for the rows |
GetColPermutation | returns the permutation used for the rows |
FactorizeMatrix | Factorizes a matrix using SuperLU |
Solve | Solves A x = b using factorization computed by SuperLU |
FactorizeMatrix | Factorizes a matrix using UmfPack |
Solve | Solves A x = b using factorization computed by UmfPack |
FactorizeMatrix | Factorizes a matrix using Wsmp |
Solve | Solves A x = b using factorization computed by Wsmp |
FactorizeMatrix | Factorizes a matrix using Seldon |
Solve | Solves A x = b using factorization computed by Seldon |
FactorizeMatrix | Factorizes a matrix using cholmod |
Solve | Solves A x = b using Cholesky factorization computed by Cholmod |
Mlt | Computes L x or LT where L is a Cholmod factor |
GetLU | performs a LU factorization |
SolveLU | uses LU factorization to solve a linear system |
GetAndSolveLU | solves a sparse linear system with the default direct solver |
SparseSolve | solves a sparse linear system with the default direct solver |
FindSparseOrdering | computes matrix ordering to reduce fill-in during factorisation |
GetCholesky | performs a Cholesky factorization |
SolveCholesky | solves L x = b or LT x = b once GetCholesky has been called |
MltCholesky | computes y = L x or y = LT x once GetCholesky has been called |
GetSchurMatrix | forms Schur complement |
void ShowMessages(); void HideMessages(); void ShowFullHistory();
ShowMessages
allows the direct solver to display informations about the factorization and resolution phases, while HideMessages
forbids any message to be displayed. ShowFullHistory
displays all the possible messages the direct solver is able to give. By default, no messages are displayed.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A; // you declare a Mumps structure MatrixMumps<double> mat_lu; // you can display messages for the factorization : mat_lu.ShowMessages(); GetLU(A, mat_lu); // then hide messages for each resolution mat_lu.HideMessages(); SolveLU(mat_lu, x);
Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx
int GetM(); int GetN();
This method returns the number of rows (or columns) of the matrix. For direct solvers, we consider only square matrices.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A; // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you factorize the matrix mat_lu.Factorize(A); // then you can use GetM, since A has been cleared int n = mat_lu.GetM(); cout << "Number of rows : " << n << endl;
Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx
size_t GetMemorySize() const;
This method returns the memory used by the object in bytes.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A; // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you factorize the matrix mat_lu.Factorize(A); // then you can use GetMemorySize to know space taken by the factorization size_t n = mat_lu.GetMemorySize(); cout << "Size of A in megabytes : " << double(n)/(1024*1024) << endl;
Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx
int GetTypeOrdering();
This method returns the ordering algorithm used by the direct solver.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A; // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // ordering to be used ? int type_ordering = mat_lu.GetTypeOrdering();
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx
void SelectOrdering(int type);
This method sets the ordering algorithm used by the direct solver. For Mumps, Pastix, SuperLU and UmfPack, the available orderings (and their numbers) are detailed in the documentation of each direct solver. For the class SparseDirectSolver, the ordering is listed in SparseMatrixOrdering :
AUTO is the default ordering, and means that the code will select the more "natural" ordering for the specified direct solver (e.g. SCOTCH with Pastix, COLAMD with UmfPack). USER means that the code assumes that the user provides manually the permutation array through SetPermutation method. For a solver such as MatrixMumps, MatrixPastix, etc, the method SelectOrdering uses the convention of each direct solver (you have to look to the documentation of each solver).
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A; // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you can specify an ordering : mat_lu.SelectOrdering(SparseMatrixOrdering::QAMD); // then you can factorize with this ordering algorithm mat_lu.Factorize(A); // for a given solver such as MatrixMumps: MatrixMumps<double> mat_mumps; // SelectOrdering does not use the convention described above // but the convention described in the solver documentation // For Mumps, 5 is Metis ordering mat_mumps.SelectOrdering(5);
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx
void SelectParallelOrdering(int type);
This method sets the ordering parallel algorithm used by the direct solver. It is currently only used for MUMPS.
// for a given solver such as MatrixMumps: MatrixMumps<double> mat_mumps; // SelectOrdering does not use the convention described above // but the convention described in the solver documentation // For Mumps, 5 is Metis ordering mat_mumps.SelectOrdering(5); // SelectParallelOrdering is used only for distributed matrices // 1 => ptscotch, 2 =>parmetis mat_mumps.SelectParallelOrdering(1);
void SetPermutation(IVect& );
This method sets the ordering permutation array used by the direct solver. It is up to the user to check that this array is valid.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you specify how A will be reordered by giving directly new row numbers IVect permutation(n); permutation.Fill(); mat_lu.SetPermutation(permutation); // then you can factorize with this ordering mat_lu.Factorize(A);
Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx
int GetNumberOfThreadPerNode() const;
This method returns the number of threads for each node. It is only relevant for Pastix.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // 8 threads per node if each node contains 8 cores mat_lu.SetNumberOfThreadPerNode(8); // then you can factorize with this ordering mat_lu.Factorize(A); // you can check the number of threads (should be equal to 8 here) int nb_threads = mat_lu.GetNumberOfThreadPerNode();
Pastix.cxx
SparseDirectSolver.cxx
void SetNumberOfThreadPerNode(int n);
This method sets the number of threads for each node. It is only relevant for Pastix.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // 8 threads per node if each node contains 8 cores mat_lu.SetNumberOfThreadPerNode(8); // then you can factorize with this ordering mat_lu.Factorize(A);
Pastix.cxx
SparseDirectSolver.cxx
void SelectDirectSolver(int type);
This method sets the direct solver to use, you can choose between :
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you select which solver you want to use mat_lu.SelectDirectSolver(mat_lu.MUMPS); // then you can factorize with this solver mat_lu.Factorize(A);
void SelectDirectSolver(int type);
This method sets the Cholesky solver to use, you can choose between :
// you fill a symmetric sparse matrix (assumed positive definite) Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you declare a sparse Cholesky Solver SparseCholeskySolver<double> mat_chol; // you select which solver you want to use mat_chol.SelectDirectSolver(mat_chol.PASTIX); // then you can factorize with this solver mat_chol.Factorize(A);
SparseCholeskyFactorisation.cxx
void SetNonSymmetricIlut();
This method tells to use non-symmetric incomplete factorization if ILUT is selected as a direct solver.
// you fill a sparse matrix Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you select which solver you want to use mat_lu.SelectDirectSolver(mat_lu.ILUT); // for ILUT solver you can use non-symmetric version even though the matrix is symmetric mat_lu.SetNonSymmetricIlut(); // then you can factorize with this solver mat_lu.Factorize(A);
void SetThresholdMatrix(double); double GetThresholdMatrix() const;
The method SetThresholdMatrix sets the threshold used to drop values during the incomplete factorization. This method is useful only if ILUT is selected as a direct solver. The method GetThresholdMatrix returns the threshold currently set.
// you fill a sparse matrix Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you select which solver you want to use mat_lu.SelectDirectSolver(mat_lu.ILUT); // for ILUT solver you can use non-symmetric version even though the matrix is symmetric mat_lu.SetNonSymmetricIlut(); // dropping threshold mat_lu.SetThresholdMatrix(1e-2); // which epsilon has been set ? double eps = mat_lu.GetThresholdMatrix(); // then you can factorize with this solver mat_lu.Factorize(A);
bool IsAvailableSolver(int);
This method returns true if the solver is available or not (i.e. if you have compiled with this solver).
// you fill a sparse matrix Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you can check if your favorite solver is present if (mat_lu.IsAvailableSolver(mat_lu.MUMPS)) { // you select which solver you want to use mat_lu.SelectDirectSolver(mat_lu.MUMPS); // then you can factorize with this solver mat_lu.Factorize(A); } else cout << "recompile with Mumps" << endl;
int GetDirectSolver();
This method returns the direct solver used.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // which solver used by default ? int type_solver = mat_lu.GetDirectSolver(); if (type_solver == mat_lu.SELDON_SOLVER) cout << "Warning : this solver is slow" << endl;
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx
void GetInfoFactorization();
This method returns the error code provided by the used direct solver. For SparseDirectSolver, the error codes are listed in an enum attribute, and can be :
For specific solvers (MatrixMumps, MatrixUmfPack, etc), the error code is described in the documentation of each solver.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A; // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you factorize the matrix mat_lu.Factorize(A); // to know if there is a problem int info = mat_lu.GetInfoFactorization(); if (info == mat_lu.OUT_OF_MEMORY) { cout << "The matrix is too large, not enough memory" << endl; } // if you are using directly a given solver MatrixMumps<double> mat_mumps; mat_mumps.Factorize(A); int info = mat_mumps.GetInfoFactorization(); // info is described in Mumps documentation if (info != 0) { cout << "MUMPS Error = " << info << endl; }
Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
bool UseInteger8 const();
This method returns true if the current solver is using 64-bits integers (integer*8 in Fortran).
// you declare a sparse Solver MatrixPastix<double> mat_lu; // you can check if the current version is using 64-bits integers or not bool use_int8 = mat_lu.UseInteger8();
Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseSolver.cxx
void Factorize(Matrix&); void Factorize(Matrix&, bool);
This method factorizes the given matrix. In parallel execution, this method will consider that the linear system to solve is restricted to the current processor. For example, you can use this method to factorize independant linear systems. If the matrix is distributed overall severall processors, you should call FactorizeDistributed or use the class SparseDistributedSolver.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you factorize the matrix mat_lu.Factorize(A); // to know if there is a problem int info = mat_lu.GetInfoFactorization(); if (info == mat_lu.OUT_OF_MEMORY) { cout << "The matrix is too large, not enough memory" << endl; } // once the matrix is factorized, you can solve systems Vector<double> x(n); mat_lu.Solve(x);
void Factorize(Matrix&); void Factorize(Matrix&, bool);
This method factorizes the given matrix. In parallel execution, this method will consider that the linear system to solve is restricted to the current processor. For example, you can use this method to factorize independant linear systems. If the matrix is distributed overall severall processors, you should use the class DistributedCholeskySolver.
// you fill a sparse matrix Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you declare a sparse Solver SparseCholeskySolver<double> mat_chol; // you factorize the matrix mat_chol.Factorize(A); // once the matrix is factorized, you can solve systems Vector<double> x(n); x.FillRand(); mat_col.Solve(SeldonNoTrans, x); mat_col.Solve(SeldonTrans, x);
SparseCholeskyFactorisation.cxx
void Solve(Vector&); void Solve(SeldonTranspose, Vector&);
void Solve(Matrix<T, General, ColMajor>&); void Solve(SeldonTranspose, Matrix<T, General, ColMajor>&);
This method computes the solution of A x = b
or AT x = b
, assuming that Factorize has been called before.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a sparse Solver SparseDirectSolver<double> mat_lu; // you factorize the matrix mat_lu.Factorize(A); // once the matrix is factorized, you can solve systems Vector<double> x(n), b(n); b.Fill(); x = b; mat_lu.Solve(x); // to solve A^T x = b : x = b; mat_lu.Solve(SeldonTrans, x); // you can solve system with multiple right hand sides Matrix<double, General, ColMajor> B(n, 10); B.FillRand(); // B is overwritten by the solution mat_lu.Solve(B); // and transpose system can be solved with multiple right hand sides B.FillRand(); mat_lu.Solve(SeldonTrans, B);
void Solve(SeldonTranspose, Vector&);
This method computes the solution of L x = b
or LT x = b
, assuming that Factorize has been called before.
// you fill a symmetric sparse matrix Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you declare a sparse Cholesky Solver SparseCholeskySolver<double> mat_chol; // you factorize the matrix mat_chol.Factorize(A); // once the matrix is factorized, you can solve systems // for Cholesky factorisation, it will solve either L x = b or L^T x = b // so you need to call the method twice to recover the solution (since A = L L^T) x = b; mat_chol.Solve(SeldonNoTrans, x); mat_chol.Solve(SeldonTrans, x);
SparseCholeskyFactorisation.cxx
void Mlt(SeldonTranspose, Vector&);
This method computes the matrix-vector product L x or LT x, once the Cholesky factorization (A = L LT) has been computed.
// for Cholesky factorisation, it will // compute either L x or L^T x // the result is overwritten in x // filling A A.Reallocate(n, n); // factorisation of A SparseCholeskySolver<double> mat_chol; mat_chol.Factorize(A); // computation of y = A x Vector<double> x(n), y(n); y = x; mat_chol.Mlt(SeldonTrans, y); mat_chol.Mlt(SeldonNoTrans, y);
SparseCholeskyFactorisation.cxx
void Mlt(const SeldonTranspose, Vector&);
This method computes the matrix-vector product L x or LT x, once the Cholesky factorization (A = L LT) has been computed.
// for Cholesky factorisation, it will // compute either L x or L^T x // the result is overwritten in x // filling A A.Reallocate(n, n); // factorisation of A DistributedCholeskySolver<double> mat_chol; mat_chol.Factorize(A); // computation of y = A x Vector<double> x(n), y(n); y = x; mat_chol.Mlt(SeldonTrans, y); mat_chol.Mlt(SeldonNoTrans, y);
SparseCholeskyFactorisation.cxx
void FactorizeDistributed(MPI::Comm& comm, Vector& Ptr, Vector& Ind, Vector& Val, IVect& glob_num, bool sym, bool keep_matrix);
void FactorizeDistributedMatrix(MPI::Comm& comm, Vector& Ptr, Vector& Ind, Vector& Val, IVect& glob_num, bool sym);
This method factorizes a distributed matrix, which is given through arrays Ptr, Ind, Val (CSC format). glob_num is a local to global array (glob_num(i) is the global row number of local row i). Each column of the global system is assumed to be distributed to one processor and only one. Each processor is assumed to have at least one column affected to its-self. Arrays Ptr and Ind may consist of 64-bit integers (in order to be compatible with 64-bit versions of direct solvers). If sym is true, the matrix is symmetric, and we assume that Ptr, Ind, Val are representing the lower part of the matrix. If sym is false, the matrix is considered non-symmetric. The communicator given in argument regroup all the processors involved in the factorization. This method is working only if you have selected Pastix, Mumps or SuperLU (SuperLU_DIST has been compiled and used). We recommend to not call this function directly and use the class SparseDistributedSolver that will call this function.
// initialization of MPI_Init_thread needed if Pastix has been compiled // with threads, otherwise you can use MPI_Init int required = MPI_THREAD_MULTIPLE; int provided = -1; MPI_Init_thread(&argc, &argv, required, &provided); // declaration of the sparse solve SparseDirectSolver<double> mat_lu; // considered global matrix // A = |1.5 1 0 0 -0.3 | // | 1 2.0 0 -1.0 0 | // | 0 0 2.0 0 0.8 | // | 0 -1.0 0 3.0 1.2 | // | -0.3 0.0 0.8 1.2 3.0 | // global right hand side (solution is 1, 2, 3, 4, 5) // B = |2 1 10 16 21.9| if (MPI::COMM_WORLD.Get_rank() == 0) { // on first processor, we provide columns 1, 2 and 5 // only lower part since matrix is symmetric int n = 3; Matrix<double, General, ArrayColSparse> A(5, n); A(0, 0) = 1.5; A(1,0) = 1.0; A(4,0) = -0.3; A(1,1) = 2.0; A(3,1) = -1.0; A(4,2) = 3.0; Vector<double> b(n); b(0) = 2; b(1) = 1; b(2) = 21.9; IVect num_loc(n); num_loc(0) = 0; num_loc(1) = 1; num_loc(2) = 4; // converting to csc format IVect Ptr, IndRow; Vector<double> Val; General prop; ConvertToCSC(A, prop, Ptr, IndRow, Val); // factorisation mat_lu.FactorizeDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // then solution mat_lu.SolveDistributed(MPI::COMM_WORLD, SeldonNoTrans, b, num_loc); DISP(b); } else { // on second processor, we provide columns 3 and 4 // only lower part since matrix is symmetric int n = 2; Matrix<double, General, ArrayColSparse> A(5, n); A(2, 0) = 2.0; A(4, 0) = 0.8; A(3,1) = 3.0; A(4,1) = 1.2; Vector<double> b(n); b(0) = 10; b(1) = 16; IVect num_loc(n); num_loc(0) = 2; num_loc(1) = 3; // converting to csc format IVect Ptr, IndRow; Vector<double> Val; General prop; ConvertToCSC(A, prop, Ptr, IndRow, Val); // factorisation mat_lu.FactorizeDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // then solution mat_lu.SolveDistributed(MPI::COMM_WORLD, SeldonNoTrans, b, num_loc); DISP(b); } MPI_Finalize();
Mumps.cxx
Pastix.cxx
SparseDirectSolver.cxx
void PerformAnalysisDistributed(MPI::Comm& comm, Vector& Ptr, Vector& Ind, Vector& Val, IVect& glob_num, bool sym, bool keep_matrix);
void PerformFactorizationDistributed(MPI::Comm& comm, Vector& Ptr, Vector& Ind, Vector& Val, IVect& glob_num, bool sym, bool keep_matrix);
This method factorizes a distributed matrix, which is given through arrays Ptr, Ind, Val (CSC format). glob_num is a local to global array (glob_num(i) is the global row number of local row i). Each column of the global system is assumed to be distributed to one processor and only one. Each processor is assumed to have at least one column affected to its-self. Arrays Ptr and Ind may consist of 64-bit integers (in order to be compatible with 64-bit versions of direct solvers). If sym is true, the matrix is symmetric, and we assume that Ptr, Ind, Val are representing the lower part of the matrix. If sym is false, the matrix is considered non-symmetric. The communicator given in argument regroup all the processors involved in the factorization. This method is working only if you have selected Pastix, Mumps or SuperLU (SuperLU_DIST has been compiled and used). We recommend to not call this function directly and use the class SparseDistributedSolver that will call this function. PerformAnalysis only performs a symbolic factorization whereas PerformFactorization completes the numerical factorization.
// initialization of MPI_Init_thread needed if Pastix has been compiled // with threads, otherwise you can use MPI_Init int required = MPI_THREAD_MULTIPLE; int provided = -1; MPI_Init_thread(&argc, &argv, required, &provided); // declaration of the sparse solve SparseDirectSolver<double> mat_lu; // considered global matrix // A = |1.5 1 0 0 -0.3 | // | 1 2.0 0 -1.0 0 | // | 0 0 2.0 0 0.8 | // | 0 -1.0 0 3.0 1.2 | // | -0.3 0.0 0.8 1.2 3.0 | // global right hand side (solution is 1, 2, 3, 4, 5) // B = |2 1 10 16 21.9| if (MPI::COMM_WORLD.Get_rank() == 0) { // on first processor, we provide columns 1, 2 and 5 // only lower part since matrix is symmetric int n = 3; Matrix<double, General, ArrayColSparse> A(5, n); A(0, 0) = 1.5; A(1,0) = 1.0; A(4,0) = -0.3; A(1,1) = 2.0; A(3,1) = -1.0; A(4,2) = 3.0; Vector<double> b(n); b(0) = 2; b(1) = 1; b(2) = 21.9; IVect num_loc(n); num_loc(0) = 0; num_loc(1) = 1; num_loc(2) = 4; // converting to csc format IVect Ptr, IndRow; Vector<double> Val; General prop; ConvertToCSC(A, prop, Ptr, IndRow, Val); // analysis mat_lu.PerformAnalysisDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // factorisation mat_lu.PerformFactorizationDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // then solution mat_lu.SolveDistributed(MPI::COMM_WORLD, SeldonNoTrans, b, num_loc); DISP(b); // if the pattern is the same as previously, but the values are different // only numerical factorisation need to be called Val.FillRand(); mat_lu.PerformFactorizationDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // then solution mat_lu.SolveDistributed(MPI::COMM_WORLD, SeldonNoTrans, b, num_loc); DISP(b); } else { // on second processor, we provide columns 3 and 4 // only lower part since matrix is symmetric int n = 2; Matrix<double, General, ArrayColSparse> A(5, n); A(2, 0) = 2.0; A(4, 0) = 0.8; A(3,1) = 3.0; A(4,1) = 1.2; Vector<double> b(n); b(0) = 10; b(1) = 16; IVect num_loc(n); num_loc(0) = 2; num_loc(1) = 3; // converting to csc format IVect Ptr, IndRow; Vector<double> Val; General prop; ConvertToCSC(A, prop, Ptr, IndRow, Val); // analysis mat_lu.PerformAnalysisDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // factorisation mat_lu.PerformFactorizationDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // then solution mat_lu.SolveDistributed(MPI::COMM_WORLD, SeldonNoTrans, b, num_loc); DISP(b); // if the pattern is the same as previously, but the values are different // only numerical factorisation need to be called Val.FillRand(); mat_lu.PerformFactorizationDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // then solution mat_lu.SolveDistributed(MPI::COMM_WORLD, SeldonNoTrans, b, num_loc); DISP(b); } MPI_Finalize();
Mumps.cxx
Pastix.cxx
SparseDirectSolver.cxx
void SolveDistributed(MPI::Comm& comm, Vector& x, IVect& glob_num);
void SolveDistributed(SeldonTrans, MPI::Comm& comm, Vector& x, IVect& glob_num);
This method solves distributed linear system (or its transpose), once FactorizeDistributed has been called. This method is working only if you have selected Pastix or Mumps.
// initialization of MPI_Init_thread needed if Pastix has been compiled // with threads, otherwise you can use MPI_Init int required = MPI_THREAD_MULTIPLE; int provided = -1; MPI_Init_thread(&argc, &argv, required, &provided); // declaration of the sparse solve SparseDirectSolver<double> mat_lu; // considered global matrix // A = |1.5 1 0 0 -0.3 | // | 1 2.0 0 -1.0 0 | // | 0 0 2.0 0 0.8 | // | 0 -1.0 0 3.0 1.2 | // | -0.3 0.0 0.8 1.2 3.0 | // global right hand side (solution is 1, 2, 3, 4, 5) // B = |2 1 10 16 21.9| if (MPI::COMM_WORLD.Get_rank() == 0) { // on first processor, we provide columns 1, 2 and 5 // only lower part since matrix is symmetric int n = 3; Matrix<double, General, ArrayColSparse> A(5, n); A(0, 0) = 1.5; A(1,0) = 1.0; A(4,0) = -0.3; A(1,1) = 2.0; A(3,1) = -1.0; A(4,2) = 3.0; Vector<double> b(n); b(0) = 2; b(1) = 1; b(2) = 21.9; IVect num_loc(n); num_loc(0) = 0; num_loc(1) = 1; num_loc(2) = 4; // converting to csc format IVect Ptr, IndRow; Vector<double> Val; General prop; ConvertToCSC(A, prop, Ptr, IndRow, Val); // factorization mat_lu.FactorizeDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // then resolution mat_lu.SolveDistributed(MPI::COMM_WORLD, SeldonNoTrans, b, num_loc); DISP(b); } else { // on second processor, we provide columns 3 and 4 // only lower part since matrix is symmetric int n = 2; Matrix<double, General, ArrayColSparse> A(5, n); A(2, 0) = 2.0; A(4, 0) = 0.8; A(3,1) = 3.0; A(4,1) = 1.2; Vector<double> b(n); b(0) = 10; b(1) = 16; IVect num_loc(n); num_loc(0) = 2; num_loc(1) = 3; // converting to csc format IVect Ptr, IndRow; Vector<double> Val; General prop; ConvertToCSC(A, prop, Ptr, IndRow, Val); // factorization mat_lu.FactorizeDistributed(MPI::COMM_WORLD, Ptr, IndRow, Val, num_loc, true); // then resolution mat_lu.SolveDistributed(MPI::COMM_WORLD, SeldonNoTrans, b, num_loc); DISP(b); } MPI_Finalize();
Mumps.cxx
Pastix.cxx
SparseDirectSolver.cxx
void Clear();
This method releases the memory used by the factorization. It is available for every direct solver.
Matrix<double, General, ArrayRowSparse> A; MatrixUmfPack<double> mat_lu; // you fill A as you want // then a first factorization is achieved GetLU(A, mat_lu); // then solve needed linear systems SolveLU(mat_lu, x); // and if you need to spare memory, you can clear factorization mat_lu.Clear();
Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx
void SetPrintLevel(int level);
This method sets the level of verbosity. A level equal to 0 means that no messages will be displayed. A level equal to 2 will induce moderate display while a level equal to 6 will display more details.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a sparse Solver SparseDistributedSolver<double> mat_lu; // you select your print level mat_lu.SetPrintLevel(2); // then you can factorize mat_lu.Factorize(A);
void Factorize(Matrix&, bool keep_matrix = false, bool scale_matrix = false); void Factorize(DistributedMatrix&, bool keep_matrix = false, bool scale_matrix = false);
This method factorizes a sequential or distributed matrix. The second argument is optional, if equal to true the input matrix is kept, otherwise the matrix is erased. The third argument is optional, if equal to true the matrix is scaled before factorizing it.
// you fill a distributed matrix DistributedMatrix<double, General, ArrayRowSparse> A(n, n); // informations about distributed rows/columns through function Init A.Init(...); // you declare a sparse Solver SparseDistributedSolver<double> mat_lu; // then you can factorize mat_lu.Factorize(A); // and solve as many linear systems you want // x contains the right hand side on input, the solution on output mat_lu.Solve(x);
void Factorize(Matrix&, bool keep_matrix = false); void Factorize(DistributedMatrix&, bool keep_matrix = false);
This method factorizes a sequential or distributed matrix. The second argument is optional, if equal to true the input matrix is kept, otherwise the matrix is erased.
// you fill a distributed matrix DistributedMatrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // informations about distributed rows/columns through function Init A.Init(...); // you declare a sparse Solver DistributedCholeskySolver<double> mat_lu; // then you can factorize mat_lu.Factorize(A); // and solve as many linear systems you want // x contains the right hand side on input, the solution on output mat_lu.Solve(SeldonNoTrans, x); mat_lu.Solve(SeldonTrans, x);
void PerformAnalysis(Matrix&); void PerformFactorization(Matrix&, bool scale_matrix = false);
void PerformAnalysis(DistributedMatrix&); void PerformFactorization(DistributedMatrix&, bool scale_matrix = false);
This method performs either the symbolic or numerical factorization of a sequential or distributed matrix. The second argument is optional, if equal to true the matrix is scaled before factorizing it.
// you fill a distributed matrix DistributedMatrix<double, General, ArrayRowSparse> A(n, n); // informations about distributed rows/columns through function Init A.Init(...); // you declare a sparse Solver SparseDistributedSolver<double> mat_lu; // then you can perform a symbolic factorization // the matrix is not erased mat_lu.PerformAnalysis(A); // PerformFactorization completes the numerical factorization // and erases the input matrix mat_lu.PerformFactorization(A); // and solve as many linear systems as you want // x contains the right hand side on input, the solution on output mat_lu.Solve(x); // then you can reconstruct A A.Reallocate(n, n); // fill it again ... // if the pattern is the same, you do not need to call PerformAnalysis mat_lu.PerformFactorization(A); mat_lu.Solve(x);
void Solve(Vector& x, const Vector& b); void Solve(Vector& x); void Solve(SeldonTranspose, Vector& x);
void Solve(Matrix& x); void Solve(SeldonTranspose, Matrix& x);
This method solves a sequential or distributed linear system. For multiple right hand sides, we consider they are stored in a Matrix with storage ColMajor, each column being a different right hand side.
// you fill a distributed matrix DistributedMatrix<double, General, ArrayRowSparse> A(n, n); // informations about distributed rows/columns through function Init A.Init(...); // you declare a sparse Solver SparseDistributedSolver<double> mat_lu; // then you can factorize mat_lu.Factorize(A); // and solve as many linear systems you want Vector<double> x(n), b(n); b.FillRand(); // first syntax, the right hand side b and the solution x are both provided mat_lu.Solve(x, b); // second syntax : x contains the right hand side on input, the solution on output x = b; mat_lu.Solve(x); // third syntax : you can ask to solve A^T x = b x = b; mat_lu.Solve(SeldonTrans, x); // for multiple right hand sides, they are rearranged in a matrix // each column is a different right hand side int nb_rhs = 10; Matrix<double, General, ColMajor> X(n, nb_rhs); X.FillRand(); mat_lu.Solve(X); // you can ask to solve transpose system as well mat_lu.Solve(SeldonTrans, X);
void Solve(SeldonTranspose, Vector& x);
This method solves a sequential or distributed linear system. On input, x contains the right hand side, on ouput the solution.
// you fill a distributed matrix DistributedMatrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // informations about distributed rows/columns through function Init A.Init(...); // filling the matrix ... // you declare a sparse Solver DistributedCholeskySolver<double> mat_lu; // then you can factorize mat_lu.Factorize(A); // Cholesky factorisation A = L L^T // Solve will compute the solution of L x = y Vector<double> y(n), x; y.FillRand(); x = y; mat_lu.Solve(SeldonNoTrans, x); // or L^t x = y x = y; mat_lu.Solve(SeldonTrans, x);
void TransSolve(Vector& x); void TransSolve(Matrix& x);
This method solves the transpose of a sequential or distributed linear system. For multiple right hand sides, we consider they are stored in a Matrix with storage ColMajor, each column being a different right hand side.
// you fill a distributed matrix DistributedMatrix<double, General, ArrayRowSparse> A(n, n); // informations about distributed rows/columns through function Init A.Init(...); // you declare a sparse Solver SparseDistributedSolver<double> mat_lu; // then you can factorize mat_lu.Factorize(A); // and solve as many linear systems you want Vector<double> x(n), b(n); b.FillRand(); // you can ask to solve A^T x = b // either with Solve(SeldonTrans, x) or with TransSolve x = b; mat_lu.TransSolve(x); // for multiple right hand sides, they are rearranged in a matrix // each column is a different right hand side int nb_rhs = 10; Matrix<double, General, ColMajor> X(n, nb_rhs); X.FillRand(); mat_lu.TransSolve(X);
void EnableOutOfCore(); void DisableOutOfCore();
This method allows the direct solver to write a part of the matrix on the disk. This option is enabled only for Mumps.
void SetPivotThreshold(double eps);
This method is not available for each direct solver, it allows to set the threshold used for pivoting.
MatrixPastix<double> mat_lu; mat_lu.SetPivotThreshold(1e-8); // then you can use mat_lu to factorize and solve as usual mat_lu.FactorizeMatrix(A); mat_lu.Solve(x);
void RefineSolution(); void DoNotRefineSolution();
This method is not available for each direct solver, it includes (or not) an additional refinement step in the resolution phase. The obtained solution should be more accurate, but the cost of the solving step should be twice higher at least.
MatrixPastix<double> mat_lu; // you tell Pastix that you want a refinement mat_lu.RefineSolution(); // then you can use mat_lu to factorize and solve as usual mat_lu.FactorizeMatrix(A); mat_lu.Solve(x);
void SetCoefficientEstimationNeededMemory(double); void SetMaximumCoefficientEstimationNeededMemory(double); void SetIncreaseCoefficientEstimationNeededMemory(double)
This method is available for MUMPS only, it sets a safety coefficient to a given value (first method). then this coefficient will be multiplied by a given factor (third method) until the factorization is successful. This loop is stopped is the coefficient reaches a given maximum value (second method).
MatrixMumps<double> mat_lu; // you set the initial safety coefficient // to allocate needed memory for the factorisation mat_lu.SetCoefficientEstimationNeededMemory(1.2); // you set the increase // here it means that if the factorisation fails (because the memory allocated is not sufficient) // the safety coef will be multiplied by 1.5, and again until completion mat_lu.SetIncreaseCoefficientEstimationNeededMemory(1.5); // you set the maximum value allowed // it means that if the safety coefficient is greater than 100.0, the solver will abort // we consider that the matrix has a problem mat_lu.SetMaximumCoefficientEstimationNeededMemory(100.0); // then you can use mat_lu to factorize and solve as usual mat_lu.FactorizeMatrix(A); mat_lu.Solve(x);
void PerformAnalysis(Matrix& A); void PerformFactorization(Matrix& A);
The method "PerformAnalysis" should reorder matrix, and perform a "symbolic" factorization of the matrix, whereas the method "PerformFactorization" should perform only numerical factorization. The aim here is to reduce the amount of work when we consider a family of linear systems which have the same pattern. In that configuration, the input matrix is not cleared.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a Mumps solver (or SparseDirectSolver) MatrixMumps<double> mat_lu; // symbolic factorization mat_lu.PerformAnalysis(A); // then factorization mat_lu.PerformFactorization(A); // you can solve a system mat_lu.Solve(x); // then construct another matrix A, but with the same // pattern. For example FillRand will modify the values A.FillRand(); // and solve the new system mat_lu.PerformFactorization(A); mat_lu.Solve(x);
void FindOrdering(Matrix&, Vector<int>&); void FindOrdering(Matrix&, Vector<int>&, bool);
This method computes the new row numbers of the matrix by using available algorithms in Mumps/Pastix. It is currently not implemented for UmfPack/SuperLU.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A; // you declare a Mumps structure (it works also for MatrixPastix) MatrixMumps<double> mat_lu; IVect permutation; // we find the best numbering of A // by default, the matrix A is erased mat_lu.FindOrdering(A, permutation); // if last argument is true, A is not modified mat_lu.FindOrdering(A, permutation, true);
void FindSparseOrdering(Matrix&, Vector<int>&, int type_ordering);
This function computes a reordering array for a given matrix. The different types of ordering are listed in the method SelectOrdering. Some orderings may be unavailable if Seldon is not interfaced with direct solvers.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A; IVect permutation; // we find the best ordering for A FindSparseOrdering(A, permutation, SparseMatrixOrdering::SCOTCH);
void GetSchurMatrix(Matrix&, Vector<int>&, Matrix&); void GetSchurMatrix(Matrix&, Vector<int>&, Matrix&, bool);
This method computes the schur complement when a matrix and row numbers of the Schur matrix are provided. It is equivalent to use the function GetSchurMatrix.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a Mumps structure MatrixMumps<double> mat_lu; // then you set some row numbers num that will be associated // with a sub-matrix A22 : A = [A11 A12; A21 A22] IVect num(3); num(0) = 4; num(1) = 10; num(2) = 12; // computation of Schur complement : A22 - A21 A11^-1 A12 Matrix<double> schur_cplt; mat_lu.GetSchurMatrix(A, num, schur_cplt); // the size of matrix schur_cplt should be the same as the size of num
void GetSchurComplement(Matrix&, Vector<int>&, Matrix&);
This method computes the schur complement when a matrix and row numbers of the Schur matrix are provided. It is equivalent to use the function GetSchurMatrix.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare a solver SparseDistributedSolver<double> mat_lu; // then you set some row numbers num that will be associated // with a sub-matrix A22 : A = [A11 A12; A21 A22] IVect num(3); num(0) = 4; num(1) = 10; num(2) = 12; // computation of Schur complement : A22 - A21 A11^-1 A12 Matrix<double> schur_cplt; mat_lu.GetSchurMatrix(A, num, schur_cplt); // the size of matrix schur_cplt should be the same as the size of num
void GetLU(Matrix&, SparseDirectSolver&, bool); void GetLU(Matrix&, MatrixMumps&, bool); void GetLU(Matrix&, MatrixUmfPack&, bool); void GetLU(Matrix&, MatrixSuperLU&, bool); void GetLU(Matrix&, MatrixMumps&, bool); void GetLU(Matrix&, MatrixUmfPack&, bool); void GetLU(Matrix&, MatrixSuperLU&, bool);
This method performs a LU factorization. The last argument is optional. When omitted, the initial matrix is erased, when equal to true, the initial matrix is not modified.
// sparse matrices, use of Mumps for example MatrixMumps<double> mat_lu; Matrix<double, General, ArrayRowSparse> Asp(n, n); // you add all non-zero entries to matrix Asp // then you call GetLU to factorize the matrix GetLU(Asp, mat_lu); // Asp is empty after GetLU // you can solve Asp x = b X = B; SolveLU(mat_lu, X); // if you want to solve Asp^T x = b X = B; SolveLU(SeldonTrans, mat_lu, X); // you can also solve Asp x = b for multiple right hand sides // b is a matrix, each right hand side is a column of b Matrix<double, General, ColMajor> bmat; SolveLU(SeldonNoTrans, mat_lu, bmat); // if you want to keep initial matrix GetLU(Asp, mat_lu, true);
Mumps.cxx
UmfPack.cxx
Pastix.cxx
SuperLU.cxx
void SolveLU(MatrixMumps&, Vector&); void SolveLU(const SeldonTranspose, MatrixMumps&, Vector&); void SolveLU(MatrixMumps&, Matrix&); void SolveLU(const SeldonTranspose, MatrixMumps&, Matrix&);
void SolveLU(MatrixPastix&, Vector&); void SolveLU(const SeldonTranspose, MatrixPastix&, Vector&); void SolveLU(MatrixPastix&, Matrix&); void SolveLU(const SeldonTranspose, MatrixPastix&, Matrix&);
void SolveLU(SparseDirectSolver&, Vector&); void SolveLU(const SeldonTranspose, SparseDirectSolver&, Vector&); void SolveLU(SparseDirectSolver&, Matrix&); void SolveLU(const SeldonTranspose, SparseDirectSolver&, Matrix&);
void SolveLU(MatrixSuperLU&, Vector&); void SolveLU(const SeldonTranspose, MatrixSuperLU&, Vector&); void SolveLU(MatrixSuperLU&, Matrix&); void SolveLU(const SeldonTranspose, MatrixSuperLU&, Matrix&);
void SolveLU(MatrixUmfPack&, Vector&); void SolveLU(const SeldonTranspose, MatrixUmfPack&, Vector&); void SolveLU(MatrixUmfPack&, Matrix&); void SolveLU(const SeldonTranspose, MatrixUmfPack&, Matrix&);
void SolveLU(MatrixWsmp&, Vector&); void SolveLU(const SeldonTranspose, MatrixWsmp&, Vector&); void SolveLU(MatrixWsmp&, Matrix&); void SolveLU(const SeldonTranspose, MatrixWsmp&, Matrix&);
void SolveLU(SparseSeldonSolver&, Vector&); void SolveLU(const SeldonTranspose, SparseSeldonSolver&, Vector&); void SolveLU(SparseSeldonSolver&, Matrix&); void SolveLU(const SeldonTranspose, SparseSeldonSolver&, Matrix&);
This method uses the LU factorization computed by GetLU
in order to solve a linear system or its transpose. The right hand side is overwritten by the result. An example is given in the documentation of GetLU.
Mumps.cxx
UmfPack.cxx
Pastix.cxx
SuperLU.cxx
void GetCholesky(Matrix&, MatrixPastix&, bool keep = false); void GetCholesky(Matrix&, MatrixCholmod&, bool keep = false); void GetCholesky(Matrix&, int print_level = 0);
This method performs a Cholesky factorization of a symmetric positive definite matrix. The last argument is optional. When omitted, the initial matrix is erased, when equal to true, the initial matrix is not modified. The last syntax can be used to perform a Cholesky factorization of a matrix of type ArrayRowSymSparse without pivoting (very slow). The last argument is the level of verbosity (0 = no messages are displayed).
// sparse matrices, use of Cholmod for example MatrixCholmod mat_chol; Matrix<double, Symmetric, ArrayRowSymSparse> Asp(n, n); // you add all non-zero entries to matrix Asp // then you call GetCholesky to factorize the matrix GetCholesky(Asp, mat_lu, true); // you can solve Asp x = b X = B; SolveCholesky(SeldonNoTrans, mat_chol, X); SolveCholesky(SeldonTrans, mat_chol, X); // or compute y = L x Vector<double> y = X; MltCholesky(SeldonNoTrans, mat_chol, y); // if your matrix is already ordered correctly // and small enough, you can call GetCholesky directly // but usually it is slow, it is better to use // the interface with Pastix or Cholmod GetCholesky(Asp); // SolveCholesy and MltCholesky are available directly X = B; SolveCholesky(SeldonNoTrans, Asp, X); SolveCholesky(SeldonTrans, Asp, X); y = X; MltCholesky(SeldonNoTrans, Asp, y); // for better efficiency, you can convert Asp to RowSymSparse Matrix<double, Symmetric, RowSymSparse> C; Copy(Asp, C); // SolveCholesky and MltCholesky should be more efficient X = B; SolveCholesky(SeldonNoTrans, C, X); SolveCholesky(SeldonTrans, C, X); y = X; MltCholesky(SeldonNoTrans, C, y);
Cholmod.cxx
Pastix.cxx
SparseCholeskyFactorisation.cxx
void SolveCholesky(SeldonTranspose, MatrixCholmod&, Vector&); void SolveCholesky(SeldonTranspose, MatrixPastix&, Vector&); void SolveCholesky(SeldonTranspose, Matrix&, Vector&);
This method uses the Cholesky factorization (A = L LT) computed by GetCholesky
in order to solve the system L x = b or LT x = b. The right hand side b is overwritten by the result x. An example is given in the documentation of GetCholesky.
Cholmod.cxx
Pastix.cxx
SparseCholeskyFactorisation.cxx
void MltCholesky(SeldonTranspose, MatrixCholmod&, Vector&); void MltCholesky(SeldonTranspose, MatrixPastix&, Vector&); void MltCholesky(SeldonTranspose, Matrix&, Vector&);
This method uses the Cholesky factorization (A = L LT) computed by GetCholesky
in order to compute y = L x or y = LT x. The input vector x is overwritten by the result y. An example is given in the documentation of GetCholesky.
Cholmod.cxx
Pastix.cxx
SparseCholeskyFactorisation.cxx
void GetSchurMatrix(Matrix&, MatrixMumps&, Vector<int>&, Matrix&);
This method computes the so-called Schur matrix (or Schur complement) from a given matrix.
MatrixMumps<double> mat_lu; Matrix<double, General, ArrayRowSparse> A(n, n); // you add all non-zero entries to matrix A // then you specify row numbers for schur matrix IVect num(5); num.Fill(); // somehow, A can be written under the form A = [A11 A12; A21 A22] // A22 is related to row numbers of the Schur matrix // Schur matrix is dense Matrix<double> mat_schur(5, 5); GetSchurMatrix(A, mat_lu, num, mat_schur); // then you should obtain A22 - A21*inv(A11)*A12 -> mat_schur
void FactorizeMatrix(Matrix& A);
This method completes the Cholesky factorization (A = L LT) by calling Cholmod.
MatrixCholmod<double> mat_chol; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Cholesky factorization (A = L L^T) // the L factor is stored in mat_chol mat_chol.FactorizeMatrix(A); // then you can solve L y = b Vector<double> y(n), b(n); b.FillRand(); y = b; mat_chol.Solve(SeldonNoTrans, y); // and L^T x = y to obtain the solution of A x = b Vector<double> x(y); mat_chol.Solve(SeldonTrans, x);
void Solve(const SeldonTranspose&, Vector& x);
This method solves L x = b or LT x = b by calling Cholmod. The L factor is assumed to have been previously computed (by calling FactorizeMatrix). On input, the user provides the right hand side in vector x, on output x contains the solution.
MatrixCholmod<double> mat_chol; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Cholesky factorization (A = L L^T) // the L factor is stored in mat_chol mat_chol.FactorizeMatrix(A); // then you can solve L y = b Vector<double> y(n), b(n); b.FillRand(); y = b; mat_chol.Solve(SeldonNoTrans, y); // and L^T x = y to obtain the solution of A x = b Vector<double> x(y); mat_chol.Solve(SeldonTrans, x);
void Mlt(const SeldonTranspose&, Vector& x);
This method computes y = L x or y = LT x by calling Cholmod. The L factor is assumed to have been previously computed (by calling FactorizeMatrix). On input, the user provides the vector x, on output y contains the product with L or its transpose.
MatrixCholmod<double> mat_chol; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Cholesky factorization (A = L L^T) // the L factor is stored in mat_chol mat_chol.FactorizeMatrix(A); // then you can compute y = L x Vector<double> y(n), x(n); x.FillRand(); y = x; mat_chol.Mlt(SeldonNoTrans, y); // or y = L^T x y = x; mat_chol.Mlt(SeldonTrans, x);
void FactorizeMatrix(Matrix&); void FactorizeMatrix(Matrix&, bool);
This method factorizes the given matrix. By default, the input matrix is cleared after the factorization. If you want to keep the input_matrix, you have to provide true in the second argument. In parallel execution, this method will consider that the linear system to solve is restricted to the current processor. For example, you can use this method to factorize independant linear systems. If the matrix is distributed overall severall processors, you should call FactorizeDistributed or use the class SparseDistributedSolver.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare the mumps solver MatrixMumps<double> mat_lu; // you factorize the matrix mat_lu.FactorizeMatrix(A); // to know if there is a problem int info = mat_lu.GetInfoFactorization(); if (info == mat_lu.OUT_OF_MEMORY) { cout << "The matrix is too large, not enough memory" << endl; } // once the matrix is factorized, you can solve systems Vector<double> x(n); mat_lu.Solve(x); // filling another matrix A.Reallocate(n, n); A.Get(0, 2) = 1.0; // ... // if you want to keep the input matrix after the factorization mat_lu.FactorizeMatrix(A, true);
void Solve(Vector&); void Solve(SeldonTranspose, Vector&); void Solve(SeldonTranspose, Matrix<T, General, ColMajor>&);
This method computes the solution of A x = b
or AT x = b
, assuming that GetLU
(or FactorizeMatrix) has been called before. This is equivalent to use function SolveLU.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare the mumps solver MatrixMumps<double> mat_lu; // you factorize the matrix mat_lu.FactorizeMatrix(A); // once the matrix is factorized, you can solve systems Vector<double> x(n), b(n); b.Fill(); x = b; mat_lu.Solve(x); // to solve A^T x = b : x = b; mat_lu.Solve(SeldonTrans, x); // you can solve system with multiple right hand sides Matrix<double, General, ColMajor> B(n, 10); B.FillRand(); // B is overwritten by the solution mat_lu.Solve(SeldonNoTrans, B); // and transpose system can be solved with multiple right hand sides B.FillRand(); mat_lu.Solve(SeldonTrans, B);
void FactorizeMatrix(Matrix&); void FactorizeMatrix(Matrix&, bool);
This method factorizes the given matrix. By default, the input matrix is cleared after the factorization. If you want to keep the input_matrix, you have to provide true in the second argument.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare the mumps solver MatrixPardiso<double> mat_lu; // you factorize the matrix mat_lu.FactorizeMatrix(A); // once the matrix is factorized, you can solve systems Vector<double> x(n); mat_lu.Solve(x); // filling another matrix A.Reallocate(n, n); A.Get(0, 2) = 1.0; // ... // if you want to keep the input matrix after the factorization mat_lu.FactorizeMatrix(A, true);
void Solve(Vector&); void Solve(SeldonTranspose, Vector&); void Solve(SeldonTranspose, Matrix<T, General, ColMajor>&);
This method computes the solution of A x = b
or AT x = b
, assuming that GetLU
(or FactorizeMatrix) has been called before. This is equivalent to use function SolveLU.
// you fill a sparse matrix Matrix<double, General, ArrayRowSparse> A(n, n); // you declare the mumps solver MatrixPardiso<double> mat_lu; // you factorize the matrix mat_lu.FactorizeMatrix(A); // once the matrix is factorized, you can solve systems Vector<double> x(n), b(n); b.Fill(); x = b; mat_lu.Solve(x); // to solve A^T x = b : x = b; mat_lu.Solve(SeldonTrans, x); // you can solve system with multiple right hand sides Matrix<double, General, ColMajor> B(n, 10); B.FillRand(); // B is overwritten by the solution mat_lu.Solve(SeldonNoTrans, B); // and transpose system can be solved with multiple right hand sides B.FillRand(); mat_lu.Solve(SeldonTrans, B);
void FactorizeMatrix(Matrix& A);
This method completes the Cholesky or LU factorization (A = L LT or A = LU) by calling Pastix.
MatrixPastix<double> mat_pastix; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Crout factorization (A = L D L^T) // for unsymmetric matrices, it is the LU factorization (A = L U) mat_pastix.FactorizeMatrix(A); // then you can solve A x = b Vector<double> x(n), b(n); b.FillRand(); x = b; mat_pastix.Solve(SeldonNoTrans, y);
void Solve(const Vector& x); void Solve(const SeldonTranspose&, Vector& x); void Solve(const SeldonTranspose&, Matrix& x);
For a LU (or Crout) factorization, this method solves A x = b or AT x = b by calling Pastix. You can provide multiple right hand sides by providing a matrix. Each column of this matrix is a right hand side. For a Cholesky factorization, this method solves L x = b or LT x = b by calling Pastix. The L factor is assumed to have been previously computed (by calling FactorizeMatrix). On input, the user provides the right hand side in vector x, on output x contains the solution.
MatrixPastix<double> mat_pastix; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Crout factorization (A = L D L^T) mat_pastix.FactorizeMatrix(A); // then you can solve A x = b Vector<double> x(n), b(n); b.FillRand(); x = b; mat_pastix.Solve(SeldonNoTrans, y); // you can also solve A^T x = b x = b; mat_pastix.Solve(SeldonTrans, y); // or solve A x = b (or A^T x = b) with multiple right hand sides int nrhs = 4; Matrix<double, General, ColMajor> bmat(n, nrhs); bmat.FillRand(); mat_pastix.Solve(SeldonTrans, bmat);
void Mlt(const SeldonTranspose&, Vector& x);
This method computes y = L x or y = LT x by calling Pastix. The L factor is assumed to have been previously computed (by calling FactorizeMatrix). On input, the user provides the vector x, on output y contains the product with L or its transpose.
MatrixPastix<double> mat_pastix; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Cholesky factorization (A = L L^T) // the L factor is stored in mat_pastix mat_pastix.SetCholeskyFacto(true); mat_pastix.FactorizeMatrix(A); // then you can compute y = L x Vector<double> y(n), x(n); x.FillRand(); y = x; mat_pastix.Mlt(SeldonNoTrans, y); // or y = L^T x y = x; mat_pastix.Mlt(SeldonTrans, x);
void SetCholeskyFacto(bool);
By default, MatrixPastix computes a LU factorization (or LDLT factorization for a symmetric matrix). If you want to complete a Cholesky factorization, you need to call this method.
MatrixPastix<double> mat_pastix; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Cholesky factorization (A = L L^T) // the L factor is stored in mat_pastix mat_pastix.SetCholeskyFacto(true); mat_pastix.FactorizeMatrix(A); // then you can compute y = L x Vector<double> y(n), x(n); x.FillRand(); y = x; mat_pastix.Mlt(SeldonNoTrans, y); // or y = L^T x y = x; mat_pastix.Mlt(SeldonTrans, x);
void GetAndSolveLU(Matrix& A, Vector& x); void SparseSolve(Matrix& A, Vector& x);
These two functions are identical : they compute the solution of a sparse linear system by using the class SparseDirectSolver. The matrix given on input is cleared after the computation. If you want to solve many linear systems with the same matrix, it is better to use GetLU and SolveLU such that the factorization stage (GetLU) is performed once. Usually, this stage is much more expensive than the solution stage (SolveLU).
Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the solution A x = b Vector<double> x(n), b(n); b.FillRand(); x = b; GetAndSolveLU(A, x); // A is cleared and x contains the solution
void FactorizeMatrix(Matrix& A);
This method completes the LU factorization by calling SuperLU.
MatrixSuperLU<double> mat_lu; Matrix<double, General, ArrayRowSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the LU factorization mat_lu.FactorizeMatrix(A); // then you can solve A x = b mat_lu.Solve(SeldonNoTrans, y);
void Solve(const Vector& x); void Solve(const SeldonTranspose&, Vector& x); void Solve(const SeldonTranspose&, Matrix& x);
This method solves A x = b or AT x = b by calling SuperLU. On input, the user provides the right hand side in vector x, on output x contains the solution.
MatrixSuperLU<double> mat_lu; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Crout factorization (A = L D L^T) mat_lu.FactorizeMatrix(A); // then you can solve A x = b Vector<double> x(n), b(n); b.FillRand(); x = b; mat_lu.Solve(SeldonNoTrans, y); // you can also solve A^T x = b x = b; mat_lu.Solve(SeldonTrans, y); // or solve A x = b (or A^T x = b) with multiple right hand sides int nrhs = 4; Matrix<double, General, ColMajor> bmat(n, nrhs); bmat.FillRand(); mat_lu.Solve(SeldonTrans, bmat);
const Vector<int>& GetRowPermutation(); const Vector<int>& GetColPermutation();
The method GetRowPermutation returns the permutation used for the rows, whereas GetColPermutation returns the permutation used for the columns.
MatrixSuperLU<double> mat_lu; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the LU factorization mat_lu.FactorizeMatrix(A); // then you can retrieve the row permutation used to factorize the matrix Vector<int> row_p = mat_lu.GetRowPermutation(); // and for columns Vector<int> col_p = mat_lu.GetColPermutation();
void FactorizeMatrix(Matrix& A);
This method completes the LU factorization by calling UmfPack.
MatrixUmfPack<double> mat_lu; Matrix<double, General, ArrayRowSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the LU factorization mat_lu.FactorizeMatrix(A); // then you can solve A x = b mat_lu.Solve(SeldonNoTrans, y);
void Solve(const Vector& x); void Solve(const SeldonTranspose&, Vector& x); void Solve(const SeldonTranspose&, Matrix& x);
This method solves A x = b or AT x = b by calling UmfPack. On input, the user provides the right hand side in vector x, on output x contains the solution.
MatrixUmfPack<double> mat_lu; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the LU factorization mat_lu.FactorizeMatrix(A); // then you can solve A x = b Vector<double> x(n), b(n); b.FillRand(); x = b; mat_lu.Solve(SeldonNoTrans, y); // you can also solve A^T x = b x = b; mat_lu.Solve(SeldonTrans, y); // or solve A x = b (or A^T x = b) with multiple right hand sides int nrhs = 4; Matrix<double, General, ColMajor> bmat(n, nrhs); bmat.FillRand(); mat_lu.Solve(SeldonTrans, bmat);
void FactorizeMatrix(Matrix& A);
This method completes the LU factorization by calling Wsmp.
MatrixWsmp<double> mat_lu; Matrix<double, General, ArrayRowSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the LU factorization mat_lu.FactorizeMatrix(A); // then you can solve A x = b mat_lu.Solve(SeldonNoTrans, y);
void Solve(const Vector& x); void Solve(const SeldonTranspose&, Vector& x); void Solve(const SeldonTranspose&, Matrix& x);
This method solves A x = b or AT x = b by calling Wsmp. On input, the user provides the right hand side in vector x, on output x contains the solution.
MatrixWsmp<double> mat_lu; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Crout factorization (A = L D L^T) mat_lu.FactorizeMatrix(A); // then you can solve A x = b Vector<double> x(n), b(n); b.FillRand(); x = b; mat_lu.Solve(SeldonNoTrans, y); // you can also solve A^T x = b x = b; mat_lu.Solve(SeldonTrans, y); // or solve A x = b (or A^T x = b) with multiple right hand sides int nrhs = 4; Matrix<double, General, ColMajor> bmat(n, nrhs); bmat.FillRand(); mat_lu.Solve(SeldonTrans, bmat);
void FactorizeMatrix(Matrix& A);
This method completes the LU factorization. It is very slow compared to direct solvers interfaced such as Mumps, Pastix, etc.
SparseSeldonSolver<double> mat_lu; Matrix<double, General, ArrayRowSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the LU factorization mat_lu.FactorizeMatrix(A); // then you can solve A x = b mat_lu.Solve(SeldonNoTrans, y);
void Solve(const Vector& x); void Solve(const SeldonTranspose&, Vector& x);
This method solves A x = b or AT x = b. On input, the user provides the right hand side in vector x, on output x contains the solution.
SparseSeldonSolver<double> mat_lu; Matrix<double, Symmetric, ArrayRowSymSparse> A(n, n); // you can fill A A.AddInteraction(0, 0, 2.5); // etc // and then computes the Crout factorization (A = L D L^T) mat_lu.FactorizeMatrix(A); // then you can solve A x = b Vector<double> x(n), b(n); b.FillRand(); x = b; mat_lu.Solve(SeldonNoTrans, y); // you can also solve A^T x = b x = b; mat_lu.Solve(SeldonTrans, y);