Dinv_gj Subroutine

subroutine Dinv_gj(a)

Arguments

Type IntentOptional Attributes Name
real(kind=8), intent(inout), dimension(:,:) :: a

Calls

proc~~dinv_gj~~CallsGraph proc~dinv_gj Dinv_gj swap swap proc~dinv_gj->swap

Source Code

subroutine Dinv_gj(a)
  real(8), dimension(:,:), intent(inout) :: a
  integer, dimension(size(a,1))      :: ipiv,indxr,indxc
  !these arrays are used for bookkeeping on the pivoting.
  !integer                            :: nn
  logical, dimension(size(a,1))      :: lpiv
  real(8)                            :: pivinv
  real(8), dimension(size(a,1))      :: dumc
  integer, target                    :: irc(2)
  integer                            :: i,l,n
  integer, pointer                   :: irow,icol
  real(8)                            :: zero=0.d0, one=1.d0
  n=size(a,1)
  irow => irc(1)
  icol => irc(2)
  ipiv=0
  do i=1,n
     !main loop over columns to be reduced.
     lpiv = (ipiv == 0)
     !begin search for a pivot element.
     irc=maxloc(abs(a),outerand(lpiv,lpiv))
     ipiv(icol)=ipiv(icol)+1
     if (ipiv(icol) > 1) stop 'gaussj:singular matrix (1)'
     !we now have the pivot element, so we interchange
     !rows, if needed, to put the pivot element on the diagonal. the columns
     !are not physically interchanged, only relabeled:
     !indxc(i),the column of the ith pivot element, is the ith column that is
     !reduced, while indxr(i) is the row in which that pivot element was
     !originally located. if indxr(i) = indxc(i) there is an implied column
     !interchange. with this form of bookkeeping, the inverse matrix will be
     !scrambled by
     !columns.
     if (irow /= icol) call swap(a(irow,:),a(icol,:))
     indxr(i)=irow !we are now ready to divide the pivot row by the pivot element,
     !located at irow and icol.
     indxc(i)=icol
     if (a(icol,icol) == zero) stop 'gaussj:singular matrix (2)'
     pivinv=one/a(icol,icol)
     a(icol,icol)= one !cmplx(one,zero)
     a(icol,:)=a(icol,:)*pivinv
     dumc=a(:,icol)
     !next, we reduce the rows, except for the pivot one, of course.
     a(:,icol)     = zero !cmplx
     a(icol,icol)  = pivinv
     a(1:icol-1,:) = a(1:icol-1,:) - outerprod(dumc(1:icol-1),a(icol,:))
     a(icol+1:,:)  = a(icol+1:,:)  - outerprod(dumc(icol+1:),a(icol,:))
  end do
  !it only remains to unscramble the solution in view of the column
  !interchanges.
  !we do this by interchanging pairs of columns in the reverse order that the
  !permutation
  !was built up.
  do l=n,1,-1
     call swap(a(:,indxr(l)),a(:,indxc(l)))
  end do
contains
  function outerand(a,b)
    implicit none
    logical, dimension(:), intent(in)   :: a,b
    logical, dimension(size(a),size(b)) :: outerand
    outerand = spread(a,dim=2,ncopies=size(b)).and.spread(b,dim=1,ncopies=size(a))
  end function outerand
  function outerprod(a,b)
    real(8), dimension(:), intent(in) :: a,b
    real(8), dimension(size(a),size(b)) :: outerprod
    outerprod = spread(a,dim=2,ncopies=size(b)) * &
         spread(b,dim=1,ncopies=size(a))
  end function outerprod
end subroutine Dinv_gj