dhefa.inc Source File


Source Code

!----------------------------------------------------------------------------------------------------------------------------------!
!()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()!
!----------------------------------------------------------------------------------------------------------------------------------!
!>
!!### DESCRIPTION
!!   This routine is a modification of the LINPACK routine DGEFA and
!!   performs an LU decomposition of an upper Hessenberg matrix A.
!!   There are two options available:
!!
!!          (1)  performing a fresh factorization
!!          (2)  updating the LU factors by adding a row and a
!!               column to the matrix A.
!!
!!   DHEFA factors an upper Hessenberg matrix by elimination.
!!
!!### ON ENTRY
!!
!!   A
!!
!!   : the matrix to be factored.
!!
!!   LDA
!!
!!   : the leading dimension of the array  A .
!!
!!   N
!!
!!   : the order of the matrix  A .
!!
!!   JOB
!!
!!       JOB = 1    means that a fresh factorization of the
!!                  matrix A is desired.
!!       JOB .ge. 2 means that the current factorization of A
!!                  will be updated by the addition of a row
!!                  and a column.
!!
!!### ON RETURN
!!
!!   A
!!
!!   : an upper triangular matrix and the multipliers
!!     which were used to obtain it.
!!
!!     The factorization can be written  A = L*U  where
!!     L is a product of permutation and unit lower
!!     triangular matrices and U is upper triangular.
!!
!!   IPVT
!!
!!   : an integer vector of pivot indices.
!!
!!   INFO
!!
!!            = 0  normal value.
!!            = k  if  U(k,k) .eq. 0.0 .  This is not an error
!!                 condition for this subroutine, but it does
!!                 indicate that DHESL will divide by zero if called.
!!
!-----------------------------------------------------------------------
!      Modification of LINPACK, by Peter Brown, LLNL.
!      Written 7/20/83.  This version dated 6/20/2001.
!
!      BLAS called: DAXPY, IDAMAX
!-----------------------------------------------------------------------
subroutine dhefa(A,Lda,N,Ipvt,Info,Job)
!
integer , intent(in)          :: Lda
real(kind=dp) , intent(inout) :: A(Lda,*)
integer , intent(in)          :: N
integer , intent(inout)       :: Ipvt(*)
integer , intent(out)         :: Info
integer , intent(in)          :: Job
!
integer :: j , k , km1 , kp1 , l , nm1
real(kind=dp) :: t
!
   if ( Job>1 ) then
   !
   !  The old factorization of A will be updated.  A row and a column
   !  has been added to the matrix A.
   !  N-1 is now the old order of the matrix.
   !
      nm1 = N - 1
   !
   !  Perform row interchanges on the elements of the new column, and
   !  perform elimination operations on the elements using the multipliers.
   !
      if ( nm1>1 ) then
         do k = 2 , nm1
            km1 = k - 1
            l = Ipvt(km1)
            t = A(l,N)
            if ( l/=km1 ) then
               A(l,N) = A(km1,N)
               A(km1,N) = t
            endif
            A(k,N) = A(k,N) + A(k,km1)*t
         enddo
      endif
   !
   !  Complete update of factorization by decomposing last 2x2 block.
   !
      Info = 0
   !
   !         Find L = pivot index
   !
      l = idamax(2,A(nm1,nm1),1) + nm1 - 1
      Ipvt(nm1) = l
   !
   !         Zero pivot implies this column already triangularized
   !
      if ( A(l,nm1)==0.0D0 ) then
         Info = nm1
      else
   !
   !            Interchange if necessary
   !
         if ( l/=nm1 ) then
            t = A(l,nm1)
            A(l,nm1) = A(nm1,nm1)
            A(nm1,nm1) = t
         endif
   !
   !            Compute multipliers
   !
         t = -1.0D0/A(nm1,nm1)
         A(N,nm1) = A(N,nm1)*t
   !
   !            Row elimination with column indexing
   !
         t = A(l,N)
         if ( l/=nm1 ) then
            A(l,N) = A(nm1,N)
            A(nm1,N) = t
         endif
         A(N,N) = A(N,N) + t*A(N,nm1)
      endif
      Ipvt(N) = N
      if ( A(N,N)==0.0D0 ) Info = N
   else
   !
   !  A new facorization is desired.  This is essentially the LINPACK
   !  code with the exception that we know there is only one nonzero
   !  element below the main diagonal.
   !
   !      Gaussian elimination with partial pivoting
   !
      Info = 0
      nm1 = N - 1
      if ( nm1>=1 ) then
         do k = 1 , nm1
            kp1 = k + 1
   !
   !         Find L = pivot index
   !
            l = idamax(2,A(k,k),1) + k - 1
            Ipvt(k) = l
   !
   !         Zero pivot implies this column already triangularized
   !
            if ( A(l,k)==0.0D0 ) then
               Info = k
            else
   !
   !            Interchange if necessary
   !
               if ( l/=k ) then
                  t = A(l,k)
                  A(l,k) = A(k,k)
                  A(k,k) = t
               endif
   !
   !            Compute multipliers
   !
               t = -1.0D0/A(k,k)
               A(k+1,k) = A(k+1,k)*t
   !
   !            Row elimination with column indexing
   !
               do j = kp1 , N
                  t = A(l,j)
                  if ( l/=k ) then
                     A(l,j) = A(k,j)
                     A(k,j) = t
                  endif
                  call daxpy(N-k,t,A(k+1,k),1,A(k+1,j),1)
               enddo
            endif
         enddo
      endif
      Ipvt(N) = N
      if ( A(N,N)==0.0D0 ) Info = N
      return
   endif
end subroutine dhefa