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).

Installation of external librairies

MUMPS

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 :

  • Download scotch
  • sudo apt install zlib1g-dev (to have the real timing library -lrt)
  • cd scotch_xxx/src
  • cp Make.inc/Makefile.inc.i686_pc_linux2 Makefile.inc
  • You have other model files "Makefile.inc" in the directory Make.inc depending on the used architecture
  • If your machine is a single-core machine, you can edit Makefile.inc and remove thread-related flags
  • For a sequential library : make scotch esmumps
  • For a parallel library, replace gcc by mpicc in Makefile.inc and type : make scotch ptscotch esmumps ptesmumps

For the installation of Metis (and ParMetis in parallel), you can read the documentation of Metis, or follow these basic instructions

  • Download Metis 5.1.0
  • tar zxvf metis-5.1.0.tar.gz
  • cd metis-5.1.0
  • make config
  • make
  • mv build/my_arch/libmetis/libmetis.a .

For ParMetis (version 4.0.3), the procedure is similar with a make config followed by a make.

UMFPACK/CHOLMOD

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 :

  • Download SuiteSparse
  • tar zxvf SuiteSparse-5-10.0.tar.gz
  • cd SuiteSparse
  • Modify the file SuiteSparse_config
    You have to enter the path where SuiteSparse is installed in the variable SUITESPARSE and handle all the lines where you see the characters ?=
  • make library

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.

SuperLU

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

  • Download SuperLU
  • tar zxvf superlu_5.2.2.tar.gz
  • cd SuperLU_5.2.2
  • Copy MAKE_INC/make.linux to the file make.inc, specify the variable SuperLUroot, and
    SUPERLIB = /libsuperlu.a
    CFLAGS = -O3 -I.
  • make lib (only library is compiled)

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

PastiX

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 :

  • Download Pastix
  • cd pastix_release/
  • mkdir build; cd build/
  • Compile with cmake (e.g. cmake .. -DPASTIX_INT64=OFF -DPASTIX_WITH_MPI=ON -DCMAKE_INSTALL_PREFIX=PastixDir -DPASTIX_ORDERING_METIS=ON -DPASTIX_ORDERING_PTSCOTCH=OFFfor 32-bit integers)
  • make
  • make install

Pardiso

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.

Syntax

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.

Basic use

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);

Advanced use

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);

Methods of SparseDirectSolver :

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


Methods of SparseCholeskySolver :

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


Methods specific to SparseDistributedSolver (class inherited from SparseDirectSolver)

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


Methods specific to DistributedCholeskySolver (class inherited from SparseCholeskySolver)

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


Methods in class VirtualSparseDirectSolver (base class for direct solvers) :

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)


Methods specific to MatrixMumps (class inherited from VirtualSparseDirectSolver)

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


Methods specific to MatrixPardiso (class inherited from VirtualSparseDirectSolver)

FactorizeMatrix Factorizes a matrix using Pardiso
Solve Solves A x = b using factorization computed by Pardiso


Methods specific to MatrixPastix (class inherited from VirtualSparseDirectSolver)

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


Methods specific to MatrixSuperLU (class inherited from VirtualSparseDirectSolver)

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


Methods specific to MatrixUmfPack (class inherited from VirtualSparseDirectSolver)

FactorizeMatrix Factorizes a matrix using UmfPack
Solve Solves A x = b using factorization computed by UmfPack


Methods specific to MatrixWsmp (class inherited from VirtualSparseDirectSolver)

FactorizeMatrix Factorizes a matrix using Wsmp
Solve Solves A x = b using factorization computed by Wsmp


Methods specific to SparseSeldonSolver (class inherited from VirtualSparseDirectSolver)

FactorizeMatrix Factorizes a matrix using Seldon
Solve Solves A x = b using factorization computed by Seldon


Methods specific to MatrixCholmod (class inherited from VirtualSparseDirectSolver)

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


Functions :

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



ShowMessages, HideMessages, ShowFullHistory

Syntax :

  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.

Example :

// 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);

Location :

Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx

GetM, GetN

Syntax :

  int GetM();
  int GetN();

This method returns the number of rows (or columns) of the matrix. For direct solvers, we consider only square matrices.

Example :

// 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;

Location :

Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx

GetMemorySize

Syntax :

  size_t GetMemorySize() const;

This method returns the memory used by the object in bytes.

Example :

// 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;

Location :

Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx

GetTypeOrdering

Syntax :

  int GetTypeOrdering();

This method returns the ordering algorithm used by the direct solver.

Example :

// 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();

Location :

SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx

SelectOrdering

Syntax :

  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 :

  • IDENTITY : no reordering
  • REVERSE_CUTHILL_MCKEE : reverse Cuthill-McKee algorithm (Seldon)
  • PORD : ordering defined in Mumps (Mumps)
  • SCOTCH : ordering provided by Scotch library (Pastix)
  • METIS : ordering provided by Metis library (Mumps)
  • AMD : Approximate Minimum Degree (UmfPack)
  • COLAMD : Column Approximate Minimum Degree (UmfPack)
  • QAMD : Quasi Approximate Minimum Degree (Mumps)
  • USER : Permutation array directly set by the user
  • AUTO : Ordering chosen automatically by the direct solver
  • AMF : Ordering provided by Mumps
  • PARMETIS : Ordering provided by ParMetis library (distributed matrix)
  • PTSCOTCH : Ordering provided by Scotch (distributed matrix)
  • MMD_AT_PLUS_A : multiple minimum degree on profile of A + transpose(A) provided by SuperLU
  • MMD_ATA : multiple minimum degree on profile of A * transpose(A) provided by SuperLU

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).

Example :

// 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);

Location :

SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx

SelectParallelOrdering

Syntax :

  void SelectParallelOrdering(int type);

This method sets the ordering parallel algorithm used by the direct solver. It is currently only used for MUMPS.

Example :

// 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);

Location :

SparseSolver.cxx
Mumps.cxx

SetPermutation

Syntax :

  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.

Example :

// 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);

Location :

Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx

GetNumberOfThreadPerNode

Syntax :

  int GetNumberOfThreadPerNode() const;

This method returns the number of threads for each node. It is only relevant for Pastix.

Example :

// 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();

Location :

Pastix.cxx
SparseDirectSolver.cxx

SetNumberOfThreadPerNode

Syntax :

  void SetNumberOfThreadPerNode(int n);

This method sets the number of threads for each node. It is only relevant for Pastix.

Example :

// 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);

Location :

Pastix.cxx
SparseDirectSolver.cxx

SelectDirectSolver

Syntax :

  void SelectDirectSolver(int type);

This method sets the direct solver to use, you can choose between :

  • SELDON_SOLVER : Basic sparse solver proposed by Seldon (very slow)
  • UMFPACK
  • SUPERLU
  • MUMPS
  • PASTIX
  • ILUT : Incomplete factorization (approximate)
  • PARDISO
  • WSMP

Example :

// 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);

Location :

SparseDirectSolver.cxx

SelectDirectSolver

Syntax :

  void SelectDirectSolver(int type);

This method sets the Cholesky solver to use, you can choose between :

  • CHOLMOD
  • PASTIX
  • SELDON_SOLVER : Basic sparse solver proposed by Seldon (very slow)

Example :

// 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);

Location :

SparseCholeskyFactorisation.cxx

SetNonSymmetricIlut

Syntax :

  void SetNonSymmetricIlut();

This method tells to use non-symmetric incomplete factorization if ILUT is selected as a direct solver.

Example :

// 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);

Location :

SparseDirectSolver.cxx

SetThresholdMatrix, GetThresholdMatrix

Syntax :

  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.

Example :

// 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);

Location :

SparseDirectSolver.cxx

IsAvailableSolver

Syntax :

  bool IsAvailableSolver(int);

This method returns true if the solver is available or not (i.e. if you have compiled with this solver).

Example :

// 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;

Location :

SparseDirectSolver.cxx

GetDirectSolver

Syntax :

  int GetDirectSolver();

This method returns the direct solver used.

Example :

// 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;

Location :

SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx

GetInfoFactorization

Syntax :

  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 :

  • FACTO_OK : successful factorization (= 0 )
  • STRUCTURALLY_SINGULAR_MATRIX : the matrix is structurally singular. It is probably because there is an empty row or column.
  • NUMERICALLY_SINGULAR_MATRIX : the matrix is numerically singular. It happens when a null pivot has been found, it may occur if the condition number of the matrix is very large.
  • OUT_OF_MEMORY : there is not enough memory to complete the factorization.
  • INVALID_ARGUMENT : the arguments provided to the direct solver are not correct.
  • INCORRECT_NUMBER_OF_ROWS : the number of rows specified is incorrect (usually negative or null)
  • MATRIX_INDICES_INCORRECT : the indices are incorrect (usually out of range, i.e. negative or greater than the dimensions of the matrix)
  • INVALID_PERMUTATION : the permutation array is not valid (probably, not defining a bijection).
  • ORDERING_FAILED : the computation of an appropriate ordering (by Metis, Scotch, etc) has failed
  • INTERNAL_ERROR : unknown error, you should look at the documentation of the used solver
  • OVERFLOW_32BIT : you should use 64-bits integers to avoid overflow of integers

For specific solvers (MatrixMumps, MatrixUmfPack, etc), the error code is described in the documentation of each solver.

Example :

// 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;
  }

Location :

Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx

UseInteger8

Syntax :

  bool UseInteger8 const();

This method returns true if the current solver is using 64-bits integers (integer*8 in Fortran).

Example :

// 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();

Location :

Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseSolver.cxx

Factorize

Syntax :

  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.

Example :

// 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);

Location :

SparseDirectSolver.cxx

Factorize

Syntax :

  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.

Example :

// 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);

Location :

SparseCholeskyFactorisation.cxx

Solve

Syntax :

  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.

Example :

// 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);

Location :

SparseDirectSolver.cxx

Solve

Syntax :

  void Solve(SeldonTranspose, Vector&);

This method computes the solution of L x = b or LT x = b, assuming that Factorize has been called before.

Example :

// 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);

Location :

SparseCholeskyFactorisation.cxx

Mlt

Syntax :

  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.

Example :

// 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);

Location :

SparseCholeskyFactorisation.cxx

Mlt

Syntax :

  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.

Example :

// 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);

Location :

SparseCholeskyFactorisation.cxx

FactorizeDistributed, FactorizeDistributedMatrix

Syntax :

  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.

Example :

  // 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();

Location :

Mumps.cxx
Pastix.cxx
SparseDirectSolver.cxx

PerformAnalysisDistributed, PerformFactorizationDistributed

Syntax :

  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.

Example :

  // 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();

Location :

Mumps.cxx
Pastix.cxx
SparseDirectSolver.cxx

SolveDistributed

Syntax :

  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.

Example :

  // 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();

Location :

Mumps.cxx
Pastix.cxx
SparseDirectSolver.cxx

Clear

Syntax :

  void Clear();

This method releases the memory used by the factorization. It is available for every direct solver.

Example :

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();

Location :

Mumps.cxx
UmfPack.cxx
SuperLU.cxx
Pastix.cxx
SparseDirectSolver.cxx
SparseCholeskyFactorisation.cxx

SetPrintLevel

Syntax :

  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.

Example :

// 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);

Location :

DistributedSolver.cxx

Factorize

Syntax :

  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.

Example :

// 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);

Location :

DistributedSolver.cxx

Factorize

Syntax :

  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.

Example :

// 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);

Location :

DistributedCholeskySolver.cxx

PerformAnalysis, PerformFactorization

Syntax :

  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.

Example :

// 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);

Location :

DistributedSolver.cxx

Solve

Syntax :

  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.

Example :

// 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);

Location :

DistributedSolver.cxx

Solve

Syntax :

  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.

Example :

// 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);

Location :

DistributedCholeskySolver.cxx

TransSolve

Syntax :

  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.

Example :

// 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);

Location :

DistributedSolver.cxx

EnableOutOfCore

Syntax :

  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.

Location :

Mumps.cxx

SetPivotThreshold

Syntax :

  void SetPivotThreshold(double eps);

This method is not available for each direct solver, it allows to set the threshold used for pivoting.

Example :

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);

Location :

Pastix.cxx
Wsmp.cxx

RefineSolution, DoNotRefineSolution

Syntax :

  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.

Example :

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);

Location :

Pastix.cxx
Wsmp.cxx

SetCoefficientEstimationNeededMemory, SetMaximumCoefficientEstimationNeededMemory, SetIncreaseCoefficientEstimationNeededMemory

Syntax :

  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).

Example :

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);

Location :

Pastix.cxx
Wsmp.cxx

PerformAnalysis, PerformFactorization

Syntax :

  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.

Example :

// 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);

Location :

Mumps.cxx

FindOrdering

Syntax :

  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.

Example :

// 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);

Location :

Mumps.cxx
Pastix.cxx

FindSparseOrdering

Syntax :

  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.

Example :

// you fill a sparse matrix
Matrix<double, General, ArrayRowSparse> A;
IVect permutation;
// we find the best ordering for A
FindSparseOrdering(A, permutation, SparseMatrixOrdering::SCOTCH); 

Location :

Ordering.cxx

GetSchurMatrix (only for MatrixMumps)

Syntax :

  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.

Example :

// 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

Location :

Mumps.cxx

GetSchurComplement

Syntax :

  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.

Example :

// 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

Location :

DistributedSolver.cxx

GetLU

Syntax :

  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.

Example :

// 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);

Location :

Mumps.cxx
UmfPack.cxx
Pastix.cxx
SuperLU.cxx

SolveLU

Syntax :

  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.

Location :

Mumps.cxx
UmfPack.cxx
Pastix.cxx
SuperLU.cxx

GetCholesky

Syntax :

  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).

Example :

// 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);

Location :

Cholmod.cxx
Pastix.cxx
SparseCholeskyFactorisation.cxx

SolveCholesky

Syntax :

  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.

Location :

Cholmod.cxx
Pastix.cxx
SparseCholeskyFactorisation.cxx

MltCholesky

Syntax :

  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.

Location :

Cholmod.cxx
Pastix.cxx
SparseCholeskyFactorisation.cxx

GetSchurMatrix (only for MatrixMumps)

Syntax :

  void GetSchurMatrix(Matrix&, MatrixMumps&, Vector<int>&, Matrix&);

This method computes the so-called Schur matrix (or Schur complement) from a given matrix.

Example :

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

Location :

Mumps.cxx

FactorizeMatrix (for MatrixCholdmod)

Syntax :

  void FactorizeMatrix(Matrix& A);

This method completes the Cholesky factorization (A = L LT) by calling Cholmod.

Example :

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);

Location :

Cholmod.cxx

Solve (for MatrixCholdmod)

Syntax :

  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.

Example :

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);

Location :

Cholmod.cxx

Mlt (for MatrixCholdmod)

Syntax :

  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.

Example :

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);

Location :

Cholmod.cxx

FactorizeMatrix

Syntax :

  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.

Example :

// 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);

Location :

Mumps.cxx

Solve

Syntax :

  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.

Example :

// 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);

Location :

Mumps.cxx

FactorizeMatrix

Syntax :

  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.

Example :

// 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);

Location :

Pardiso.cxx

Solve

Syntax :

  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.

Example :

// 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);

Location :

Pardiso.cxx

FactorizeMatrix (for MatrixPastix)

Syntax :

  void FactorizeMatrix(Matrix& A);

This method completes the Cholesky or LU factorization (A = L LT or A = LU) by calling Pastix.

Example :

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);

Location :

Pastix.cxx

Solve (for MatrixPastix)

Syntax :

   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.

Example :

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);

Location :

Pastix.cxx

Mlt (for MatrixPastix)

Syntax :

  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.

Example :

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);

Location :

Pastix.cxx

SetCholeskyFacto

Syntax :

  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.

Example :

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);

Location :

Pastix.cxx

SparseSolve, GetAndSolveLU

Syntax :

  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).

Example :

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

Location :

SparseDirectSolverInline.cxx

FactorizeMatrix (for MatrixSuperLU)

Syntax :

  void FactorizeMatrix(Matrix& A);

This method completes the LU factorization by calling SuperLU.

Example :

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);

Location :

SuperLU.cxx

Solve (for MatrixSuperLU)

Syntax :

   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.

Example :

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);

Location :

SuperLU.cxx

GetRowPermutation, GetColPermutation (for MatrixSuperLU)

Syntax :

  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.

Example :

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();

Location :

SuperLU.cxx

FactorizeMatrix (for MatrixUmfPack)

Syntax :

  void FactorizeMatrix(Matrix& A);

This method completes the LU factorization by calling UmfPack.

Example :

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);

Location :

UmfPack.cxx

Solve (for MatrixUmfPack)

Syntax :

   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.

Example :

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);

Location :

UmfPack.cxx

FactorizeMatrix (for MatrixWsmp)

Syntax :

  void FactorizeMatrix(Matrix& A);

This method completes the LU factorization by calling Wsmp.

Example :

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);

Location :

Wsmp.cxx

Solve (for MatrixWsmp)

Syntax :

   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.

Example :

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);

Location :

Wsmp.cxx

FactorizeMatrix (for SparseSeldonSolver)

Syntax :

  void FactorizeMatrix(Matrix& A);

This method completes the LU factorization. It is very slow compared to direct solvers interfaced such as Mumps, Pastix, etc.

Example :

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);

Location :

SparseSolver.cxx

Solve (for SparseSeldonSolver)

Syntax :

   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.

Example :

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);

Location :

SparseSolver.cxx