namespace Eigen {

/** \eigenManualPage TutorialSparse Sparse matrix manipulations

\eigenAutoToc

Manipulating and solving sparse problems involves various modules which are summarized below:

<table class="manual">
<tr><th>Module</th><th>Header file</th><th>Contents</th></tr>
<tr><td>\link SparseCore_Module SparseCore \endlink</td><td>\code#include <Eigen/SparseCore>\endcode</td><td>SparseMatrix and SparseVector classes, matrix assembly, basic sparse linear algebra (including sparse triangular solvers)</td></tr>
<tr><td>\link SparseCholesky_Module SparseCholesky \endlink</td><td>\code#include <Eigen/SparseCholesky>\endcode</td><td>Direct sparse LLT and LDLT Cholesky factorization to solve sparse self-adjoint positive definite problems</td></tr>
<tr><td>\link SparseLU_Module SparseLU \endlink</td><td>\code #include<Eigen/SparseLU> \endcode</td>
<td>%Sparse LU factorization to solve general square sparse systems</td></tr>
<tr><td>\link SparseQR_Module SparseQR \endlink</td><td>\code #include<Eigen/SparseQR>\endcode </td><td>%Sparse QR factorization for solving sparse linear least-squares problems</td></tr>
<tr><td>\link IterativeLinearSolvers_Module IterativeLinearSolvers \endlink</td><td>\code#include <Eigen/IterativeLinearSolvers>\endcode</td><td>Iterative solvers to solve large general linear square problems (including self-adjoint positive definite problems)</td></tr>
<tr><td>\link Sparse_Module Sparse \endlink</td><td>\code#include <Eigen/Sparse>\endcode</td><td>Includes all the above modules</td></tr>
</table>

\section TutorialSparseIntro Sparse matrix format

In many applications (e.g., finite element methods) it is common to deal with very large matrices where only a few coefficients are different from zero.  In such cases, memory consumption can be reduced and performance increased by using a specialized representation storing only the nonzero coefficients. Such a matrix is called a sparse matrix.

\b The \b %SparseMatrix \b class

The class SparseMatrix is the main sparse matrix representation of Eigen's sparse module; it offers high performance and low memory usage.
It implements a more versatile variant of the widely-used Compressed Column (or Row) Storage scheme.
It consists of four compact arrays:
 - \c Values: stores the coefficient values of the non-zeros.
 - \c InnerIndices: stores the row (resp. column) indices of the non-zeros.
 - \c OuterStarts: stores for each column (resp. row) the index of the first non-zero in the previous two arrays.
 - \c InnerNNZs: stores the number of non-zeros of each column (resp. row).
The word \c inner refers to an \em inner \em vector that is a column for a column-major matrix, or a row for a row-major matrix.
The word \c outer refers to the other direction.

This storage scheme is better explained on an example. The following matrix
<table class="manual">
<tr><td> 0</td><td>3</td><td> 0</td><td>0</td><td> 0</td></tr>
<tr><td>22</td><td>0</td><td> 0</td><td>0</td><td>17</td></tr>
<tr><td> 7</td><td>5</td><td> 0</td><td>1</td><td> 0</td></tr>
<tr><td> 0</td><td>0</td><td> 0</td><td>0</td><td> 0</td></tr>
<tr><td> 0</td><td>0</td><td>14</td><td>0</td><td> 8</td></tr>
</table>

and one of its possible sparse, \b column \b major representation:
<table class="manual">
<tr><td>Values:</td>        <td>22</td><td>7</td><td>_</td><td>3</td><td>5</td><td>_</td><td>14</td><td>_</td><td>1</td><td>_</td><td>17</td><td>8</td></tr>
<tr><td>InnerIndices:</td>  <td> 1</td><td>2</td><td>_</td><td>0</td><td>2</td><td>_</td><td>4</td><td>_</td><td>2</td><td>_</td><td> 1</td><td>4</td></tr>
</table>
<table class="manual">
<tr><td>OuterStarts:</td><td>0</td><td>3</td><td>5</td><td>8</td><td>10</td><td>\em 12 </td></tr>
<tr><td>InnerNNZs:</td>    <td>2</td><td>2</td><td>1</td><td>1</td><td> 2</td><td></td></tr>
</table>

Currently the elements of a given inner vector are guaranteed to be always sorted by increasing inner indices.
The \c "_" indicates available free space to quickly insert new elements.
Assuming no reallocation is needed, the insertion of a random element is therefore in `O(nnz_j)` where `nnz_j` is the number of nonzeros of the respective inner vector.
On the other hand, inserting elements with increasing inner indices in a given inner vector is much more efficient since this only requires to increase the respective \c InnerNNZs entry that is a `O(1)` operation.

The case where no empty space is available is a special case, and is referred as the \em compressed mode.
It corresponds to the widely used Compressed Column (or Row) Storage schemes (CCS or CRS).
Any SparseMatrix can be turned to this form by calling the SparseMatrix::makeCompressed() function.
In this case, one can remark that the \c InnerNNZs array is redundant with \c OuterStarts because we have the equality: `InnerNNZs[j] == OuterStarts[j+1] - OuterStarts[j]`.
Therefore, in practice a call to SparseMatrix::makeCompressed() frees this buffer.

It is worth noting that most of our wrappers to external libraries requires compressed matrices as inputs.

The results of %Eigen's operations always produces \b compressed sparse matrices.
On the other hand, the insertion of a new element into a SparseMatrix converts this later to the \b uncompressed mode.

Here is the previous matrix represented in compressed mode:
<table class="manual">
<tr><td>Values:</td>        <td>22</td><td>7</td><td>3</td><td>5</td><td>14</td><td>1</td><td>17</td><td>8</td></tr>
<tr><td>InnerIndices:</td>  <td> 1</td><td>2</td><td>0</td><td>2</td><td> 4</td><td>2</td><td> 1</td><td>4</td></tr>
</table>
<table class="manual">
<tr><td>OuterStarts:</td><td>0</td><td>2</td><td>4</td><td>5</td><td>6</td><td>\em 8 </td></tr>
</table>

A SparseVector is a special case of a SparseMatrix where only the \c Values and \c InnerIndices arrays are stored.
There is no notion of compressed/uncompressed mode for a SparseVector.


\section TutorialSparseExample First example

Before describing each individual class, let's start with the following typical example: solving the Laplace equation \f$ \Delta u = 0 \f$ on a regular 2D grid using a finite difference scheme and Dirichlet boundary conditions.
Such problem can be mathematically expressed as a linear problem of the form \f$ Ax=b \f$ where \f$ x \f$ is the vector of \c m unknowns (in our case, the values of the pixels), \f$ b \f$ is the right hand side vector resulting from the boundary conditions, and \f$ A \f$ is an \f$ m \times m \f$ matrix containing only a few non-zero elements resulting from the discretization of the Laplacian operator.

<table class="manual">
<tr><td>
\include Tutorial_sparse_example.cpp
</td>
<td>
\image html Tutorial_sparse_example.jpeg
</td></tr></table>

In this example, we start by defining a column-major sparse matrix type of double \c SparseMatrix<double>, and a triplet list of the same scalar type \c  Triplet<double>. A triplet is a simple object representing a non-zero entry as the triplet: \c row index, \c column index, \c value.

In the main function, we declare a list \c coefficients of triplets (as a std vector) and the right hand side vector \f$ b \f$ which are filled by the \a buildProblem function.
The raw and flat list of non-zero entries is then converted to a true SparseMatrix object \c A.
Note that the elements of the list do not have to be sorted, and possible duplicate entries will be summed up.

The last step consists of effectively solving the assembled problem.
Since the resulting matrix \c A is symmetric by construction, we can perform a direct Cholesky factorization via the SimplicialLDLT class which behaves like its LDLT counterpart for dense objects.

The resulting vector \c x contains the pixel values as a 1D array which is saved to a jpeg file shown on the right of the code above.

Describing the \a buildProblem and \a save functions is out of the scope of this tutorial. They are given \ref TutorialSparse_example_details "here" for the curious and reproducibility purpose.




\section TutorialSparseSparseMatrix The SparseMatrix class

\b %Matrix \b and \b vector \b properties \n

The SparseMatrix and SparseVector classes take three template arguments:
 * the scalar type (e.g., double)
 * the storage order (ColMajor or RowMajor, the default is ColMajor)
 * the inner index type (default is \c int).

As for dense Matrix objects, constructors takes the size of the object.
Here are some examples:

\code
SparseMatrix<std::complex<float> > mat(1000,2000);         // declares a 1000x2000 column-major compressed sparse matrix of complex<float>
SparseMatrix<double,RowMajor> mat(1000,2000);              // declares a 1000x2000 row-major compressed sparse matrix of double
SparseVector<std::complex<float> > vec(1000);              // declares a column sparse vector of complex<float> of size 1000
SparseVector<double,RowMajor> vec(1000);                   // declares a row sparse vector of double of size 1000
\endcode

In the rest of the tutorial, \c mat and \c vec represent any sparse-matrix and sparse-vector objects, respectively.

The dimensions of a matrix can be queried using the following functions:
<table class="manual">
<tr><td>Standard \n dimensions</td><td>\code
mat.rows()
mat.cols()\endcode</td>
<td>\code
vec.size() \endcode</td>
</tr>
<tr><td>Sizes along the \n inner/outer dimensions</td><td>\code
mat.innerSize()
mat.outerSize()\endcode</td>
<td></td>
</tr>
<tr><td>Number of non \n zero coefficients</td><td>\code
mat.nonZeros() \endcode</td>
<td>\code
vec.nonZeros() \endcode</td></tr>
</table>


\b Iterating \b over \b the \b nonzero \b coefficients \n

Random access to the elements of a sparse object can be done through the \c coeffRef(i,j) function.
However, this function involves a quite expensive binary search.
In most cases, one only wants to iterate over the non-zeros elements. This is achieved by a standard loop over the outer dimension, and then by iterating over the non-zeros of the current inner vector via an InnerIterator. Thus, the non-zero entries have to be visited in the same order than the storage order.
Here is an example:
<table class="manual">
<tr><td>
\code
SparseMatrix<double> mat(rows,cols);
for (int k=0; k<mat.outerSize(); ++k)
  for (SparseMatrix<double>::InnerIterator it(mat,k); it; ++it)
  {
    it.value();
    it.row();   // row index
    it.col();   // col index (here it is equal to k)
    it.index(); // inner index, here it is equal to it.row()
  }
\endcode
</td><td>
\code
SparseVector<double> vec(size);
for (SparseVector<double>::InnerIterator it(vec); it; ++it)
{
  it.value(); // == vec[ it.index() ]
  it.index();
}
\endcode
</td></tr>
</table>
For a writable expression, the referenced value can be modified using the valueRef() function.
If the type of the sparse matrix or vector depends on a template parameter, then the \c typename keyword is
required to indicate that \c InnerIterator denotes a type; see \ref TopicTemplateKeyword for details.


\section TutorialSparseFilling Filling a sparse matrix

Because of the special storage scheme of a SparseMatrix, special care has to be taken when adding new nonzero entries.
For instance, the cost of a single purely random insertion into a SparseMatrix is \c O(nnz), where \c nnz is the current number of non-zero coefficients.

The simplest way to create a sparse matrix while guaranteeing good performance is thus to first build a list of so-called \em triplets, and then convert it to a SparseMatrix.

Here is a typical usage example:
\code
typedef Eigen::Triplet<double> T;
std::vector<T> tripletList;
tripletList.reserve(estimation_of_entries);
for(...)
{
  // ...
  tripletList.push_back(T(i,j,v_ij));
}
SparseMatrixType mat(rows,cols);
mat.setFromTriplets(tripletList.begin(), tripletList.end());
// mat is ready to go!
\endcode
The \c std::vector of triplets might contain the elements in arbitrary order, and might even contain duplicated elements that will be summed up by setFromTriplets().
See the SparseMatrix::setFromTriplets() function and class Triplet for more details.


In some cases, however, slightly higher performance, and lower memory consumption can be reached by directly inserting the non-zeros into the destination matrix.
A typical scenario of this approach is illustrated below:
\code
1: SparseMatrix<double> mat(rows,cols);         // default is column major
2: mat.reserve(VectorXi::Constant(cols,6));
3: for each i,j such that v_ij != 0
4:   mat.insert(i,j) = v_ij;                    // alternative: mat.coeffRef(i,j) += v_ij;
5: mat.makeCompressed();                        // optional
\endcode

- The key ingredient here is the line 2 where we reserve room for 6 non-zeros per column. In many cases, the number of non-zeros per column or row can easily be known in advance. If it varies significantly for each inner vector, then it is possible to specify a reserve size for each inner vector by providing a vector object with an `operator[](int j)` returning the reserve size of the \c j-th inner vector (e.g., via a `VectorXi` or `std::vector<int>`). If only a rought estimate of the number of nonzeros per inner-vector can be obtained, it is highly recommended to overestimate it rather than the opposite. If this line is omitted, then the first insertion of a new element will reserve room for 2 elements per inner vector.
- The line 4 performs a sorted insertion. In this example, the ideal case is when the \c j-th column is not full and contains non-zeros whose inner-indices are smaller than \c i. In this case, this operation boils down to trivial O(1) operation.
- When calling `insert(i,j)` the element `i`, `j` must not already exists, otherwise use the `coeffRef(i,j)` method that will allow to, e.g., accumulate values. This method first performs a binary search and finally calls `insert(i,j)` if the element does not already exist. It is more flexible than `insert()` but also more costly.
- The line 5 suppresses the remaining empty space and transforms the matrix into a compressed column storage.



\section TutorialSparseFeatureSet Supported operators and functions

Because of their special storage format, sparse matrices cannot offer the same level of flexibility than dense matrices.
In Eigen's sparse module we chose to expose only the subset of the dense matrix API which can be efficiently implemented.
In the following \em sm denotes a sparse matrix, \em sv a sparse vector, \em dm a dense matrix, and \em dv a dense vector.

\subsection TutorialSparse_BasicOps Basic operations

%Sparse expressions support most of the unary and binary coefficient wise operations:
\code
sm1.real()   sm1.imag()   -sm1                    0.5*sm1
sm1+sm2      sm1-sm2      sm1.cwiseProduct(sm2)
\endcode
However, <strong>a strong restriction is that the storage orders must match</strong>. For instance, in the following example:
\code
sm4 = sm1 + sm2 + sm3;
\endcode
sm1, sm2, and sm3 must all be row-major or all column-major.
On the other hand, there is no restriction on the target matrix sm4.
For instance, this means that for computing \f$ A^T + A \f$, the matrix \f$ A^T \f$ must be evaluated into a temporary matrix of compatible storage order:
\code
SparseMatrix<double> A, B;
B = SparseMatrix<double>(A.transpose()) + A;
\endcode

Binary coefficient wise operators can also mix sparse and dense expressions:
\code
sm2 = sm1.cwiseProduct(dm1);
dm2 = sm1 + dm1;
dm2 = dm1 - sm1;
\endcode
Performance-wise, the adding/subtracting sparse and dense matrices is better performed in two steps. For instance, instead of doing `dm2 = sm1 + dm1`, better write:
\code
dm2 = dm1;
dm2 += sm1;
\endcode
This version has the advantage to fully exploit the higher performance of dense storage (no indirection, SIMD, etc.), and to pay the cost of slow sparse evaluation on the few non-zeros of the sparse matrix only.


%Sparse expressions also support transposition:
\code
sm1 = sm2.transpose();
sm1 = sm2.adjoint();
\endcode
However, there is no `transposeInPlace()` method.


\subsection TutorialSparse_Products Matrix products

%Eigen supports various kind of sparse matrix products which are summarize below:
  - \b sparse-dense:
    \code
dv2 = sm1 * dv1;
dm2 = dm1 * sm1.adjoint();
dm2 = 2. * sm1 * dm1;
    \endcode
  - \b symmetric \b sparse-dense. The product of a sparse symmetric matrix with a dense matrix (or vector) can also be optimized by specifying the symmetry with `selfadjointView()`:
    \code
dm2 = sm1.selfadjointView<>() * dm1;          // if all coefficients of sm1 are stored
dm2 = sm1.selfadjointView<Upper>() * dm1;     // if only the upper part of sm1 is stored
dm2 = sm1.selfadjointView<Lower>() * dm1;     // if only the lower part of sm1 is stored
    \endcode
  - \b sparse-sparse. For sparse-sparse products, two different algorithms are available. The default one is conservative and preserve the explicit zeros that might appear:
    \code
sm3 = sm1 * sm2;
sm3 = 4 * sm1.adjoint() * sm2;
    \endcode
    The second algorithm prunes on the fly the explicit zeros, or the values smaller than a given threshold. It is enabled and controlled through the `prune()` functions:
    \code
sm3 = (sm1 * sm2).pruned();                  // removes numerical zeros
sm3 = (sm1 * sm2).pruned(ref);               // removes elements much smaller than ref
sm3 = (sm1 * sm2).pruned(ref,epsilon);       // removes elements smaller than ref*epsilon
    \endcode

  - \b permutations. Finally, permutations can be applied to sparse matrices too:
    \code
PermutationMatrix<Dynamic,Dynamic> P = ...;
sm2 = P * sm1;
sm2 = sm1 * P.inverse();
sm2 = sm1.transpose() * P;
    \endcode


\subsection TutorialSparse_SubMatrices Block operations

Regarding read-access, sparse matrices expose the same API than for dense matrices to access to sub-matrices such as blocks, columns, and rows. See \ref TutorialBlockOperations for a detailed introduction.
However, for performance reasons, writing to a sub-sparse-matrix is much more limited, and currently only contiguous sets of columns (resp. rows) of a column-major (resp. row-major) SparseMatrix are writable. Moreover, this information has to be known at compile-time, leaving out methods such as `block(...)` and `corner*(...)`. The available API for write-access to a SparseMatrix are summarized below:
\code
SparseMatrix<double,ColMajor> sm1;
sm1.col(j) = ...;
sm1.leftCols(ncols) = ...;
sm1.middleCols(j,ncols) = ...;
sm1.rightCols(ncols) = ...;

SparseMatrix<double,RowMajor> sm2;
sm2.row(i) = ...;
sm2.topRows(nrows) = ...;
sm2.middleRows(i,nrows) = ...;
sm2.bottomRows(nrows) = ...;
\endcode

In addition, sparse matrices expose the `SparseMatrixBase::innerVector()` and `SparseMatrixBase::innerVectors()` methods, which are aliases to the `col`/`middleCols` methods for a column-major storage, and to the `row`/`middleRows` methods for a row-major storage.

\subsection TutorialSparse_TriangularSelfadjoint Triangular and selfadjoint views

Just as with dense matrices, the `triangularView()` function can be used to address a triangular part of the matrix, and perform triangular solves with a dense right hand side:
\code
dm2 = sm1.triangularView<Lower>(dm1);
dv2 = sm1.transpose().triangularView<Upper>(dv1);
\endcode

The `selfadjointView()` function permits various operations:
 - optimized sparse-dense matrix products:
    \code
dm2 = sm1.selfadjointView<>() * dm1;          // if all coefficients of sm1 are stored
dm2 = sm1.selfadjointView<Upper>() * dm1;     // if only the upper part of sm1 is stored
dm2 = sm1.selfadjointView<Lower>() * dm1;     // if only the lower part of sm1 is stored
    \endcode
 - copy of triangular parts:
    \code
sm2 = sm1.selfadjointView<Upper>();                               // makes a full selfadjoint matrix from the upper triangular part
sm2.selfadjointView<Lower>() = sm1.selfadjointView<Upper>();      // copies the upper triangular part to the lower triangular part
    \endcode
 - application of symmetric permutations:
 \code
PermutationMatrix<Dynamic,Dynamic> P = ...;
sm2 = A.selfadjointView<Upper>().twistedBy(P);                                // compute P S P' from the upper triangular part of A, and make it a full matrix
sm2.selfadjointView<Lower>() = A.selfadjointView<Lower>().twistedBy(P);       // compute P S P' from the lower triangular part of A, and then only compute the lower part
 \endcode

Please, refer to the \link SparseQuickRefPage Quick Reference \endlink  guide for the list of supported operations. The list of linear solvers available is \link TopicSparseSystems here. \endlink

*/

}
