InvertMatrix Subroutine

public subroutine InvertMatrix(A, Ainv, n)

Invert the n-by-n matrix A by Gauss-Jordan elimination with partial pivoting, in double precision. Used once at initialization for the small (N+1) Legendre Vandermonde; A is a well-conditioned Vandermonde in an orthonormal basis, so a direct solve is appropriate.

Arguments

TypeIntentOptionalAttributesName
real(kind=real64), intent(in) :: A(1:n,1:n)
real(kind=real64), intent(out) :: Ainv(1:n,1:n)
integer, intent(in) :: n

Called by

proc~~invertmatrix~~CalledByGraph proc~invertmatrix InvertMatrix proc~buildmodaltransform BuildModalTransform proc~buildmodaltransform->proc~invertmatrix proc~init_refinementindicator2d_t Init_RefinementIndicator2D_t proc~init_refinementindicator2d_t->proc~buildmodaltransform proc~init_refinementindicator2d Init_RefinementIndicator2D proc~init_refinementindicator2d->proc~init_refinementindicator2d_t

Contents

Source Code


Source Code

  subroutine InvertMatrix(A,Ainv,n)
    !! Invert the n-by-n matrix A by Gauss-Jordan elimination with partial pivoting, in double
    !! precision. Used once at initialization for the small (N+1) Legendre Vandermonde; A is a
    !! well-conditioned Vandermonde in an orthonormal basis, so a direct solve is appropriate.
    implicit none
    integer,intent(in) :: n
    real(real64),intent(in) :: A(1:n,1:n)
    real(real64),intent(out) :: Ainv(1:n,1:n)
    ! Local
    real(real64) :: M(1:n,1:n)
    integer :: i,j,k,piv
    real(real64) :: pmax,factor,tmp

    M = A
    Ainv = 0.0_real64
    do i = 1,n
      Ainv(i,i) = 1.0_real64
    enddo

    do k = 1,n
      ! Partial pivot: find the largest-magnitude entry in column k at or below the diagonal.
      piv = k
      pmax = abs(M(k,k))
      do i = k+1,n
        if(abs(M(i,k)) > pmax) then
          pmax = abs(M(i,k))
          piv = i
        endif
      enddo
      if(pmax <= 0.0_real64) then
        print*,__FILE__,':',__LINE__,' : Error : singular Vandermonde in modal transform.'
        stop 1
      endif
      if(piv /= k) then
        do j = 1,n
          tmp = M(k,j); M(k,j) = M(piv,j); M(piv,j) = tmp
          tmp = Ainv(k,j); Ainv(k,j) = Ainv(piv,j); Ainv(piv,j) = tmp
        enddo
      endif

      ! Normalize the pivot row.
      factor = M(k,k)
      do j = 1,n
        M(k,j) = M(k,j)/factor
        Ainv(k,j) = Ainv(k,j)/factor
      enddo

      ! Eliminate column k from every other row.
      do i = 1,n
        if(i /= k) then
          factor = M(i,k)
          do j = 1,n
            M(i,j) = M(i,j)-factor*M(k,j)
            Ainv(i,j) = Ainv(i,j)-factor*Ainv(k,j)
          enddo
        endif
      enddo
    enddo

  endsubroutine InvertMatrix