The convention is that any vector or matrix type (except if it is a reference) can be instantiated with the constructors:

```
Vector V(n); // build a vector of size n.
Matrix M(n, m); // build a matrix with n rows and m columns.
```

No other constructor is used inside *Gmm++* and you should not use any other if you want your code
to be compatible with any matrix and vector type.

It is assumed that each vector type interfaced with *Gmm++* allows to
access to a component with the following syntax:

```
a = V[i]; // read the ith component of V.
V[i] = b; // write the ith component of V.
```

The write access being available if the vector is not a constant reference. For a matrix:

```
a = M(i, j); // read the component at row i and column j of M.
M(i, j) = b; // write the component at row i and column j of M.
```

Again the write access is available if the matrix is not a const reference. Generally, especially for sparse matrices, this access is not very efficient. Linear algebra procedures access to the components of the vectors and matrices via iterators. (see section *Deeper inside Gmm++*)

It is also not recommended (at all) to use the original copy operator for vectors or matrices. Generally, it will not do the appropriate job. instead, you have to use the method:

```
gmm::copy(V, W); // W <-- V
```

which works for all correctly interfaced matrix and vector type, even if `V` is not of the same type as `W` (`V` could be sparse and `W` dense for instance).

in *Gmm++*, a vector is not a (n by 1) matrix, it is a one dimensional object. If you need to use a vector as a (n by 1) column matrix or a (1 by n) row matrix, you can do it with:

```
gmm::row_vector(V) // gives a reference on V considered as
// a (1 by n) row matrix
gmm::col_vector(V) // gives a reference on V considered as
// a (n by 1) col matrix
```

In the following, the template parameter `T` will represent a scalar type like `double` or `std::complex<double>`.

*Gmm++* interfaces `std::vector<T>` so you can use it as your basic dense vector type.
If you need to interface another type of dense vector you can see in `gmm/gmm_interface.h`
some examples.

*Gmm++* provides two types of sparse vectors: `gmm::wsvector<T>` and `gmm::rsvector<T>`. `gmm::wsvector<T>` is optimized for write operations and `gmm::rsvector<T>` is optimized for read operations. It should be appropriate to use `gmm::wsvector<T>` for assembling procedures and then to copy the vector in a `gmm::rsvector<T>` for the solvers. Those two vector types can be used to create row major or column major matrices (see section *generic row and column matrices*).

The type `gmm::slvector<T>` defines a skyline vector, in the sense that only an interval of this vector is stored. With this type of vector you can build skyline matrices as `gmm::row_matrix< gmm::slvector<T> >` (see next section *generic row and column matrices*).

*Gmm++* provides the two following types of matrices: `gmm::row_matrix<VECT>` and `gmm::col_matrix<VECT>` where `VECT` should be a valid (i.e. interfaced) vector type.
Those two type of matrices store an array of `VECT` so the memory is not contiguous. Initializations are:

```
gmm::row_matrix< std::vector<double> > M1(10, 10); // dense row matrix
gmm::col_matrix< gmm::wsvector<double> > M2(5, 20); // sparse column matrix
```

Of course `gmm::row_matrix<VECT>` is a row matrix and it is impossible to access to a particular column of this matrix.

`gmm::mat_nrows(M)` gives the number of rows of a matrix and `gmm::mat_ncols(M)` the number of columns.

It is recommended to use the type:

```
gmm::dense_matrix<T>
```

to represent a dense matrix type because it is compatible with the Fortran format (column major) and some operations are interfaced with blas and Lapack (see section *Interface with BLAS, LAPACK or ATLAS*). It is considered as a column and row matrix (column preferred) which means that you can access both to the columns and rows.

However, matrix types as `gmm::row_matrix< std::vector<double> >` or `gmm::col_matrix< std::vector<double> >` represent also some dense matrices.

Similarly, `gmm::row_matrix< gmm::wsvector<double> >` or `gmm::col_matrix< gmm::rsvector<double> >` represents some sparse matrices, but *Gmm++* provides also two types of classical sparse matrix types:

```
gmm::csr_matrix<T>
gmm::csc_matrix<T>
```

The type `gmm::csr_matrix<T>` represents a compressed sparse row matrix and `gmm::csc_matrix<T>` a compressed sparse column matrix. The particularity of these two types of matrices is to be read only, in the sense that it is not possible to access at a particular component to write on it (the operation is too expansive). The only write operation permitted is `gmm::copy`. The right way to use these matrices is first to execute the write operations on another type of matrix like `gmm::row_matrix< gmm::wsvector<double> >` then to do a copy:

```
gmm::row_matrix< gmm::wsvector<double> > M1;
...
assembly operation on M1
...
M1(i,j) = b;
...
gmm::csc_matrix<double> M2;
gmm::clean(M1, 1E-12);
gmm::copy(M1, M2);
```

Matrices `gmm::csr_matrix<T>` and `gmm::csc_matrix<T>` have the advantage to have a standard format (interfacable with Fortran code) and to have a compact format (contiguous in memory). To be able to be compatible with Fortran programs a second template parameter exists on these type, you can declare:

```
gmm::csc_matrix<double, 1> M1;
gmm::csr_matrix<double, 1> M2;
```

The `1` means that a shift will be done on all the indices.