# Matrix and Vector type provided by *Gmm++*¶

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

.

## dense vectors¶

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

## sparse vectors¶

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

## skyline vectors¶

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

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

## dense matrices¶

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.

## sparse 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 (interfaceable 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.