A compressed sparse row matrix: the standard layout for sparse linear
algebra and, identically, for adjacency lists of weighted graphs.
pic_graph builds its shortest-path algorithms directly on this type.
### Layout
A csr_t holds the usual triple, all of it one-based:
row_ptr(1:nrow+1) - row_ptr(i) is the index in col_idx/values
of the first stored entry of row i, and row_ptr(i+1) - 1 the index
of its last. row_ptr(1) is always 1 and row_ptr(nrow+1) is
nnz + 1.col_idx(1:nnz) - column index of each stored entry, sorted
ascending within every row.values(1:nnz) - the matching real(dp) values.An empty row i is represented by row_ptr(i) == row_ptr(i+1), which
makes every row loop do k = row_ptr(i), row_ptr(i+1) - 1 iterate zero
times. That case is explicitly supported and tested.
### Duplicate coordinate entries are summed
build_from_coo accepts coordinate triplets in any order. Repeated
(i, j) coordinates are summed, which is the conventional
finite-element assembly semantics and makes the builder usable directly
as an assembly routine. Duplicates are not an error.
### Components are public on purpose
The three arrays and the shape are public components so that consumers
such as pic_graph can walk rows without copying. Writing to them by
hand can produce a structurally broken matrix, which is exactly what
is_valid exists to detect; matvec, transpose and row_slice call
it before touching any index, so a malformed matrix produces an
error_t rather than an out-of-bounds access.
### Usage
type(csr_t) :: a
type(error_t) :: err
real(dp) :: y(2)
call a%build_from_coo(2_default_int, 2_default_int, &
[1_default_int, 2_default_int], &
[2_default_int, 1_default_int], &
[3.0_dp, 4.0_dp], err)
call a%matvec([1.0_dp, 1.0_dp], y, err)
Compressed sparse row matrix with real(dp) values.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=default_int), | public, | allocatable | :: | col_idx(:) |
Column index of every stored entry, ascending within each row |
||
| integer(kind=default_int), | public | :: | ncol | = | 0 |
Number of columns; prefer the |
|
| integer(kind=default_int), | public | :: | nrow | = | 0 |
Number of rows; prefer the |
|
| integer(kind=default_int), | public, | allocatable | :: | row_ptr(:) |
Row start offsets, size |
||
| real(kind=dp), | public, | allocatable | :: | values(:) |
Value of every stored entry, parallel to |
| procedure, public :: build_from_coo => csr_build_from_coo | |
| procedure, public :: destroy => csr_destroy | |
| procedure, public :: is_valid => csr_is_valid | |
| procedure, public :: matvec => csr_matvec | |
| procedure, public :: n_cols => csr_n_cols | |
| procedure, public :: n_rows => csr_n_rows | |
| procedure, public :: nnz => csr_nnz | |
| procedure, public :: row_slice => csr_row_slice | |
| procedure, public :: transpose => csr_transpose |
Check that the stored triple is structurally consistent.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(csr_t), | intent(in) | :: | self | |||
| type(error_t), | intent(out), | optional | :: | err |
.true. when the matrix is structurally sound
Number of columns of the matrix.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(csr_t), | intent(in) | :: | self |
Number of rows of the matrix.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(csr_t), | intent(in) | :: | self |
Build the matrix from coordinate (COO) triplets.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(csr_t), | intent(inout) | :: | self | |||
| integer(kind=default_int), | intent(in) | :: | n_rows |
Number of rows of the assembled matrix |
||
| integer(kind=default_int), | intent(in) | :: | n_cols |
Number of columns of the assembled matrix |
||
| integer(kind=default_int), | intent(in) | :: | rows(:) |
Row coordinate of each triplet |
||
| integer(kind=default_int), | intent(in) | :: | cols(:) |
Column coordinate of each triplet |
||
| real(kind=dp), | intent(in) | :: | vals(:) |
Value of each triplet |
||
| type(error_t), | intent(out), | optional | :: | err |
Release all storage and reset the matrix to an empty 0 by 0 one.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(csr_t), | intent(inout) | :: | self |
Sparse matrix-vector product y = A*x.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(csr_t), | intent(in) | :: | self | |||
| real(kind=dp), | intent(in) | :: | x(:) |
Input vector of length |
||
| real(kind=dp), | intent(out) | :: | y(:) |
Output vector of length |
||
| type(error_t), | intent(out), | optional | :: | err |
Copy out the column indices and values stored in row i.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(csr_t), | intent(in) | :: | self | |||
| integer(kind=default_int), | intent(in) | :: | i |
Row to read, in |
||
| integer(kind=default_int), | intent(out), | allocatable | :: | cols(:) |
Column indices of row |
|
| real(kind=dp), | intent(out), | allocatable | :: | vals(:) |
Values of row |
|
| type(error_t), | intent(out), | optional | :: | err |
Build the transpose of this matrix into at.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(csr_t), | intent(in) | :: | self | |||
| type(csr_t), | intent(out) | :: | at |
Receives the transpose |
||
| type(error_t), | intent(out), | optional | :: | err |
Set err to ERROR_VALIDATION with message, when err is present.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(error_t), | intent(out), | optional | :: | err | ||
| character(len=*), | intent(in) | :: | message |
Human-readable description of the violation |
Insertion-sort one row segment lo:hi by column index.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=default_int), | intent(inout) | :: | cols(:) | |||
| real(kind=dp), | intent(inout) | :: | vals(:) | |||
| integer(kind=default_int), | intent(in) | :: | lo | |||
| integer(kind=default_int), | intent(in) | :: | hi |