1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
|
---
title: sparse
---
# The `stdlib_sparse` module
[TOC]
## Introduction
The `stdlib_sparse` module provides derived types for standard sparse matrix data structures. It also provides math kernels such as sparse matrix-vector product and conversion between matrix types.
## Sparse matrix derived types
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### The `sparse_type` abstract derived type
#### Status
Experimental
#### Description
The parent `sparse_type` is as an abstract derived type holding the basic common meta data needed to define a sparse matrix, as well as shared APIs. All sparse matrix flavors are extended from the `sparse_type`.
```Fortran
type, public, abstract :: sparse_type
integer :: nrows !! number of rows
integer :: ncols !! number of columns
integer :: nnz !! number of non-zero values
integer :: storage !! assumed storage symmetry
end type
```
The storage integer label should be assigned from the module's internal enumerator containing the following three enums:
```Fortran
enum, bind(C)
enumerator :: sparse_full !! Full Sparse matrix (no symmetry considerations)
enumerator :: sparse_lower !! Symmetric Sparse matrix with triangular inferior storage
enumerator :: sparse_upper !! Symmetric Sparse matrix with triangular supperior storage
end enum
```
In the following, all sparse kinds will be presented in two main flavors: a data-less type `<matrix>_type` useful for topological graph operations. And real/complex valued types `<matrix>_<kind>_type` containing the `data` buffer for the matrix values. The following rectangular matrix will be used to showcase how each sparse matrix holds the data internally:
$$ M = \begin{bmatrix}
9 & 0 & 0 & 0 & -3 \\
4 & 7 & 0 & 0 & 0 \\
0 & 8 & -1 & 8 & 0 \\
4 & 0 & 5 & 6 & 0 \\
\end{bmatrix} $$
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `COO`: The COOrdinates compressed sparse format
#### Status
Experimental
#### Description
The `COO`, triplet or `ijv` format defines all non-zero elements of the matrix by explicitly allocating the `i,j` index and the value of the matrix. While some implementations use separate `row` and `col` arrays for the index, here we use a 2D array in order to promote fast memory acces to `ij`.
```Fortran
type(COO_sp_type) :: COO
call COO%malloc(4,5,10)
COO%data(:) = real([9,-3,4,7,8,-1,8,4,5,6])
COO%index(1:2,1) = [1,1]
COO%index(1:2,2) = [1,5]
COO%index(1:2,3) = [2,1]
COO%index(1:2,4) = [2,2]
COO%index(1:2,5) = [3,2]
COO%index(1:2,6) = [3,3]
COO%index(1:2,7) = [3,4]
COO%index(1:2,8) = [4,1]
COO%index(1:2,9) = [4,3]
COO%index(1:2,10) = [4,4]
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `CSR`: The Compressed Sparse Row or Yale format
#### Status
Experimental
#### Description
The Compressed Sparse Row or Yale format `CSR` stores the matrix structure by compressing the row indices with a counter pointer `rowptr` enabling to know the first and last non-zero column index `col` of the given row.
```Fortran
type(CSR_sp_type) :: CSR
call CSR%malloc(4,5,10)
CSR%data(:) = real([9,-3,4,7,8,-1,8,4,5,6])
CSR%col(:) = [1,5,1,2,2,3,4,1,3,4]
CSR%rowptr(:) = [1,3,5,8,11]
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `CSC`: The Compressed Sparse Column format
#### Status
Experimental
#### Description
The Compressed Sparse Colum `CSC` is similar to the `CSR` format but values are accesed first by column, thus an index counter is given by `colptr` which enables to know the first and last non-zero row index of a given colum.
```Fortran
type(CSC_sp_type) :: CSC
call CSC%malloc(4,5,10)
CSC%data(:) = real([9,4,4,7,8,-1,5,8,6,-3])
CSC%row(:) = [1,2,4,2,3,3,4,3,4,1]
CSC%colptr(:) = [1,4,6,8,10,11]
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `ELLPACK`: ELL-pack storage format
#### Status
Experimental
#### Description
The `ELL` format stores data in a dense matrix of $nrows \times K$ in column major order. By imposing a constant number of elements per row $K$, this format will incur in additional zeros being stored, but it enables efficient vectorization as memory acces is carried out by constant sized strides.
```Fortran
type(ELL_sp_type) :: ELL
call ELL%malloc(num_rows=4,num_cols=5,num_nz_row=3)
ELL%data(1,1:3) = real([9,-3,0])
ELL%data(2,1:3) = real([4,7,0])
ELL%data(3,1:3) = real([8,-1,8])
ELL%data(4,1:3) = real([4,5,6])
ELL%index(1,1:3) = [1,5,0]
ELL%index(2,1:3) = [1,2,0]
ELL%index(3,1:3) = [2,3,4]
ELL%index(4,1:3) = [1,3,4]
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `SELL-C`: The Sliced ELLPACK with Constant blocks format
#### Status
Experimental
#### Description
The Sliced ELLPACK format `SELLC` is a variation of the `ELLPACK` format. This modification reduces the storage size compared to the `ELLPACK` format but maintaining its efficient data access scheme. It can be seen as an intermediate format between `CSR` and `ELLPACK`. For more details read [the reference](https://arxiv.org/pdf/1307.6209v1)
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
## `add`- sparse matrix data accessors
### Status
Experimental
### Description
Type-bound procedures to enable adding data in a sparse matrix.
### Syntax
`call matrix%add(i,j,v)` or
`call matrix%add(i(:),j(:),v(:,:))`
### Arguments
`i`: Shall be an integer value or rank-1 array. It is an `intent(in)` argument.
`j`: Shall be an integer value or rank-1 array. It is an `intent(in)` argument.
`v`: Shall be a `real` or `complex` value or rank-2 array. The type shall be in accordance to the declared sparse matrix object. It is an `intent(in)` argument.
## `at`- sparse matrix data accessors
### Status
Experimental
### Description
Type-bound procedures to enable requesting data from a sparse matrix.
### Syntax
`v = matrix%at(i,j)`
### Arguments
`i` : Shall be an integer value. It is an `intent(in)` argument.
`j` : Shall be an integer value. It is an `intent(in)` argument.
`v` : Shall be a `real` or `complex` value in accordance to the declared sparse matrix object. If the `ij` tuple is within the sparse pattern, `v` contains the value in the data buffer. If the `ij` tuple is outside the sparse pattern, `v` is equal `0`. If the `ij` tuple is outside the matrix pattern `(nrows,ncols)`, `v` is `NaN`.
### Example
```fortran
{!example/linalg/example_sparse_data_accessors.f90!}
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
## `spmv` - Sparse Matrix-Vector product
### Status
Experimental
### Description
Provide sparse matrix-vector product kernels for the current supported sparse matrix types.
$$y=\alpha*op(M)*x+\beta*y$$
### Syntax
`call ` [[stdlib_sparse_spmv(module):spmv(interface)]] `(matrix,vec_x,vec_y [,alpha,beta,op])`
### Arguments
`matrix`: Shall be a `real` or `complex` sparse type matrix. It is an `intent(in)` argument.
`vec_x`: Shall be a rank-1 or rank-2 array of `real` or `complex` type array. It is an `intent(in)` argument.
`vec_y`: Shall be a rank-1 or rank-2 array of `real` or `complex` type array. . It is an `intent(inout)` argument.
`alpha`, `optional` : Shall be a scalar value of the same type as `vec_x`. Default value `alpha=1`. It is an `intent(in)` argument.
`beta`, `optional` : Shall be a scalar value of the same type as `vec_x`. Default value `beta=0`. It is an `intent(in)` argument.
`op`, `optional`: In-place operator identifier. Shall be a `character(1)` argument. It can have any of the following values: `N`: no transpose, `T`: transpose, `H`: hermitian or complex transpose. These values are provided as constants by the `stdlib_sparse` module: `sparse_op_none`, `sparse_op_transpose`, `sparse_op_hermitian`
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
## Sparse matrix to matrix conversions
### Status
Experimental
### Description
This module provides facility functions for converting between storage formats.
### Syntax
`call ` [[stdlib_sparse_conversion(module):coo2ordered(interface)]] `(coo[,sort_data])`
### Arguments
`COO` : Shall be any `COO` type. The same object will be returned with the arrays reallocated to the correct size after removing duplicates. It is an `intent(inout)` argument.
`sort_data`, `optional` : Shall be a `logical` argument to determine whether data in the COO graph should be sorted while sorting the index array, default `.false.`. It is an `intent(in)` argument.
### Syntax
`call ` [[stdlib_sparse_conversion(module):from_ijv(interface)]] `(sparse,row,col[,data,nrows,ncols,num_nz_rows,chunk])`
### Arguments
`sparse` : Shall be a `COO`, `CSR`, `ELL` or `SELLC` type. The graph object will be returned with a canonical shape after sorting and removing duplicates from the `(row,col,data)` triplet. If the graph is `COO_type` no data buffer is allowed. It is an `intent(inout)` argument.
`row` : rows index array. It is an `intent(in)` argument.
`col` : columns index array. It is an `intent(in)` argument.
`data`, `optional`: `real` or `complex` data array. It is an `intent(in)` argument.
`nrows`, `optional`: number of rows, if not given it will be computed from the `row` array. It is an `intent(in)` argument.
`ncols`, `optional`: number of columns, if not given it will be computed from the `col` array. It is an `intent(in)` argument.
`num_nz_rows`, `optional`: number of non zeros per row, only valid in the case of an `ELL` matrix, by default it will computed from the largest row. It is an `intent(in)` argument.
`chunk`, `optional`: chunk size, only valid in the case of a `SELLC` matrix, by default it will be taken from the `SELLC` default attribute chunk size. It is an `intent(in)` argument.
### Example
```fortran
{!example/linalg/example_sparse_from_ijv.f90!}
```
### Syntax
`call ` [[stdlib_sparse_conversion(module):diag(interface)]] `(matrix,diagonal)`
### Arguments
`matrix` : Shall be a `dense`, `COO`, `CSR` or `ELL` type. It is an `intent(in)` argument.
`diagonal` : A rank-1 array of the same type as the `matrix`. It is an `intent(inout)` and `allocatable` argument.
#### Note
If the `diagonal` array has not been previously allocated, the `diag` subroutine will allocate it using the `nrows` of the `matrix`.
### Syntax
`call ` [[stdlib_sparse_conversion(module):dense2coo(interface)]] `(dense,coo)`
### Arguments
`dense` : Shall be a rank-2 array of `real` or `complex` type. It is an `intent(in)` argument.
`coo` : Shall be a `COO` type of `real` or `complex` type. It is an `intent(out)` argument.
### Syntax
`call ` [[stdlib_sparse_conversion(module):coo2dense(interface)]] `(coo,dense)`
### Arguments
`coo` : Shall be a `COO` type of `real` or `complex` type. It is an `intent(in)` argument.
`dense` : Shall be a rank-2 array of `real` or `complex` type. It is an `intent(out)` argument.
### Syntax
`call ` [[stdlib_sparse_conversion(module):coo2csr(interface)]] `(coo,csr)`
### Arguments
`coo` : Shall be a `COO` type of `real` or `complex` type. It is an `intent(in)` argument.
`csr` : Shall be a `CSR` type of `real` or `complex` type. It is an `intent(out)` argument.
### Syntax
`call ` [[stdlib_sparse_conversion(module):coo2csc(interface)]] `(coo,csc)`
### Arguments
`coo` : Shall be a `COO` type of `real` or `complex` type. It is an `intent(in)` argument.
`csc` : Shall be a `CSC` type of `real` or `complex` type. It is an `intent(out)` argument.
### Syntax
`call ` [[stdlib_sparse_conversion(module):csr2coo(interface)]] `(csr,coo)`
### Arguments
`csr` : Shall be a `CSR` type of `real` or `complex` type. It is an `intent(in)` argument.
`coo` : Shall be a `COO` type of `real` or `complex` type. It is an `intent(out)` argument.
### Syntax
`call ` [[stdlib_sparse_conversion(module):csr2sellc(interface)]] `(csr,sellc[,chunk])`
### Arguments
`csr` : Shall be a `CSR` type of `real` or `complex` type. It is an `intent(in)` argument.
`sellc` : Shall be a `SELLC` type of `real` or `complex` type. It is an `intent(out)` argument.
`chunk`, `optional`: chunk size for the Sliced ELLPACK format. It is an `intent(in)` argument.
### Syntax
`call ` [[stdlib_sparse_conversion(module):csr2sellc(interface)]] `(csr,ell[,num_nz_rows])`
### Arguments
`csr` : Shall be a `CSR` type of `real` or `complex` type. It is an `intent(in)` argument.
`ell` : Shall be a `ELL` type of `real` or `complex` type. It is an `intent(out)` argument.
`num_nz_rows`, `optional`: number of non zeros per row. If not give, it will correspond to the size of the longest row in the `CSR` matrix. It is an `intent(in)` argument.
### Syntax
`call ` [[stdlib_sparse_conversion(module):csc2coo(interface)]] `(csc,coo)`
### Arguments
`csc` : Shall be a `CSC` type of `real` or `complex` type. It is an `intent(in)` argument.
`coo` : Shall be a `COO` type of `real` or `complex` type. It is an `intent(out)` argument.
### Example
```fortran
{!example/linalg/example_sparse_spmv.f90!}
```
|