csr_matvec Subroutine

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

Type Bound

csr_t

Arguments

Type IntentOptional Attributes Name
class(csr_t), intent(in) :: self
real(kind=dp), intent(in) :: x(:)

Input vector of length n_cols

real(kind=dp), intent(out) :: y(:)

Output vector of length n_rows

type(error_t), intent(out), optional :: err

Calls

proc~~csr_matvec~~CallsGraph proc~csr_matvec csr_t%csr_matvec proc~csr_is_valid csr_t%csr_is_valid proc~csr_matvec->proc~csr_is_valid proc~fail~3 fail proc~csr_matvec->proc~fail~3 proc~csr_is_valid->proc~fail~3 proc~error_set error_t%error_set proc~fail~3->proc~error_set

Variables

Type Visibility Attributes Name Initial
real(kind=dp), private :: acc
integer(kind=default_int), private :: i
integer(kind=default_int), private :: k

Source Code

   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