csr_transpose Subroutine

private subroutine csr_transpose(self, at, err)

Build the transpose of this matrix into at.

at is an n_cols by n_rows matrix whose rows are, as always, sorted ascending by column index. Transposing twice reproduces the original structure and values exactly. The source is checked with is_valid first; a malformed source reports ERROR_VALIDATION and leaves at empty.

Type Bound

csr_t

Arguments

Type IntentOptional Attributes Name
class(csr_t), intent(in) :: self
type(csr_t), intent(out) :: at

Receives the transpose

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

Calls

proc~~csr_transpose~~CallsGraph proc~csr_transpose csr_t%csr_transpose proc~csr_destroy csr_t%csr_destroy proc~csr_transpose->proc~csr_destroy proc~csr_is_valid csr_t%csr_is_valid proc~csr_transpose->proc~csr_is_valid proc~csr_nnz csr_t%csr_nnz proc~csr_transpose->proc~csr_nnz proc~fail~3 fail 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
integer(kind=default_int), private :: i
integer(kind=default_int), private :: j
integer(kind=default_int), private :: k
integer(kind=default_int), private :: n_entries
integer(kind=default_int), private, allocatable :: next_free(:)

Source Code

   subroutine csr_transpose(self, at, err)
      !! Build the transpose of this matrix into `at`.
      !!
      !! `at` is an `n_cols` by `n_rows` matrix whose rows are, as always,
      !! sorted ascending by column index. Transposing twice reproduces the
      !! original structure and values exactly. The source is checked with
      !! `is_valid` first; a malformed source reports `ERROR_VALIDATION` and
      !! leaves `at` empty.
      class(csr_t), intent(in) :: self
      type(csr_t), intent(out) :: at
         !! Receives the transpose
      type(error_t), intent(out), optional :: err

      integer(default_int) :: i, k, j, n_entries
      integer(default_int), allocatable :: next_free(:)

      call at%destroy()
      if (.not. self%is_valid(err)) return

      n_entries = self%nnz()
      at%nrow = self%ncol
      at%ncol = self%nrow

      allocate (at%row_ptr(at%nrow + 1))
      allocate (at%col_idx(n_entries))
      allocate (at%values(n_entries))
      allocate (next_free(at%nrow))

      at%row_ptr = 0
      do k = 1, n_entries
         j = self%col_idx(k) + 1
         at%row_ptr(j) = at%row_ptr(j) + 1
      end do
      at%row_ptr(1) = 1
      do i = 1, at%nrow
         at%row_ptr(i + 1) = at%row_ptr(i + 1) + at%row_ptr(i)
         next_free(i) = at%row_ptr(i)
      end do

      ! walking the source in row order leaves every target row ascending
      do i = 1, self%nrow
         do k = self%row_ptr(i), self%row_ptr(i + 1) - 1
            j = self%col_idx(k)
            at%col_idx(next_free(j)) = i
            at%values(next_free(j)) = self%values(k)
            next_free(j) = next_free(j) + 1
         end do
      end do
   end subroutine csr_transpose