Sparse matrix-vector product y = A*x.
x must have n_cols elements and y exactly n_rows; anything
else reports ERROR_VALIDATION and leaves y untouched, rather than
reading past the end of either vector. The matrix is checked with
is_valid first, so a structurally broken matrix is an error and not
an out-of-bounds access; that check is O(nnz), the same order as the
product itself.
| 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 |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=dp), | private | :: | acc | ||||
| integer(kind=default_int), | private | :: | i | ||||
| integer(kind=default_int), | private | :: | k |
subroutine csr_matvec(self, x, y, err) !! Sparse matrix-vector product `y = A*x`. !! !! `x` must have `n_cols` elements and `y` exactly `n_rows`; anything !! else reports `ERROR_VALIDATION` and leaves `y` untouched, rather than !! reading past the end of either vector. The matrix is checked with !! `is_valid` first, so a structurally broken matrix is an error and not !! an out-of-bounds access; that check is O(nnz), the same order as the !! product itself. class(csr_t), intent(in) :: self real(dp), intent(in) :: x(:) !! Input vector of length `n_cols` real(dp), intent(out) :: y(:) !! Output vector of length `n_rows` type(error_t), intent(out), optional :: err integer(default_int) :: i, k real(dp) :: acc if (.not. self%is_valid(err)) return if (int(size(x), default_int) /= self%ncol) then call fail(err, "pic_csr: matvec input vector length does not match n_cols") return end if if (int(size(y), default_int) /= self%nrow) then call fail(err, "pic_csr: matvec output vector length does not match n_rows") return end if do i = 1, self%nrow acc = 0.0_dp do k = self%row_ptr(i), self%row_ptr(i + 1) - 1 acc = acc + self%values(k)*x(self%col_idx(k)) end do y(i) = acc end do end subroutine csr_matvec