MIC_spec.F
c****************************************************************
#include "author.inc"
c* $Id: MIC_spec.F,v 1.1 1995/11/14 02:19:54 turner Exp $
c*
c* Overwrite a matrix in full-storage format by a level zero
c* modified incomplete Cholesky factorization (fill elements
c* are lumped into diagonal rather than simply being dropped).
c*
c* <PARAMETER LIST>
c*
c* Input:
c* idim - leading dimension of a
c* n - actual size of a to be used
c*
c* In/Out:
c* a - matrix to be factored
c*
c* Output:
c* status - return status
c* -4 ==> breakdown
c* -1 ==> invalid argument(s)
c* 0 ==> success
c*
#include "copyright.inc"
c****************************************************************
subroutine JT_MIC_Full (idim, n, a, status)
implicit none
c
c ... Input:
integer idim, n
c
c ... In/Out:
real a(idim,n)
c
c ... Output:
integer status
c
c ... Local:
integer i, j, k
real zero
c
parameter (zero=0.0d0)
c
c ... Initialize return status.
status = 0
c
c ... Check arguments.
if (n.le.0 .or. idim.le.0 .or. n.gt.idim) then
status = -1
return
endif
c
c ... Test for zero main diagonal element.
do k=1,n
if (a(k,k) .eq. zero) then
status = -4
return
endif
enddo
c
do k=1,n-1
a(k,k) = SQRT(a(k,k))
do i=k+1,n
if (a(i,k) .ne. zero) then
a(i,k) = a(i,k) / a(k,k)
do j=i,n
if (a(k,j) .ne. zero) then
if (a(i,j) .ne. zero) then
a(i,j) = a(i,j) - a(i,k)*a(k,j)
else
a(i,i) = a(i,i) - a(i,k)*a(k,j)
endif
endif
enddo
endif
enddo
enddo
a(n,n) = SQRT(a(n,n))
c
return
end
c****************************************************************
#include "author.inc"
c* $Id: MIC_spec.F,v 1.1 1995/11/14 02:19:54 turner Exp $
c*
c* Overwrite a matrix in ELL storage format by a level zero
c* modified incomplete Cholesky factorization.
c*
c* Note that the main difference between this routine and
c* JT_IC_ELL is that the j loop goes from i+1 to n rather
c* than from 1 to maxnz. This increases cost significantly
c* for large systems. Is there a better way?
c*
c* NOTE: No pivoting is performed.
c*
c* <PARAMETER LIST>
c*
c* Input:
c* idim - leading dimension of arrays
c* n - number of rows to use
c* maxnz - maximum number of non-zero elements in any row
c* ja - column map for array a
c*
c* In/Out:
c* a - original matrix on input, factored matrix on output
c*
c* Output:
c* status - return status
c* -4 ==> breakdown
c* -1 ==> invalid argument(s)
c* 0 ==> success
c*
#include "copyright.inc"
c****************************************************************
subroutine JT_MIC_ELL (idim, n, maxnz, ja, a, status)
implicit none
c
c ... Input:
integer idim, maxnz, n
integer ja(idim,maxnz)
c
c ... In/Out:
real a(idim,maxnz)
c
c ... Output:
integer status
c
c ... Local:
integer i, ij, j, k, kj, kk
real zero
c
parameter (zero=0.0d0)
c
c ... Initialize return status.
status = 0
c
c ... Check arguments.
if (n.le.0 .or. idim.le.0 .or. maxnz.le.0 .or. n.gt.idim) then
status = -1
return
endif
c
c ... Test for zero main diagonal element.
do k=1,n
if (a(k,1) .eq. zero) then
status = -4
return
endif
enddo
c
do k=1,n-1
a(k,1) = SQRT(a(k,1))
c
c .... Loop over rows k+1 to n.
do i=k+1,n
c
c ..... Find kk such that ja(i,kk) = k. Note that if one is found,
c we also know that a(i,kk) is non-zero.
do kk=2,maxnz
if (ja(i,kk) .eq. 0) then
c
c ....... Out of elements, so a(i,kk) = 0, so bail out and get
c another i.
goto 35
elseif (ja(i,kk) .eq. k) then
c
c ....... Found kk.
goto 15
endif
enddo
c
c ..... Didn't find kk, so a(i,kk) = 0, so bail out and get another i.
goto 35
c
15 continue
a(i,kk) = a(i,kk) / a(k,1)
c
c ..... Loop over columns k+1 to n.
do j=k+1,n
c
c ...... Find kj such that ja(k,kj) = j. Note that if one is found,
c we also know that a(k,kj) is non-zero.
do kj=2,maxnz
if (ja(k,kj) .eq. 0) then
c
c ........ Out of elements, so a(k,kj) = 0, so bail out and get
c another j.
goto 30
elseif (ja(k,kj) .eq. j) then
c
c ........ Found kj.
goto 20
endif
enddo
c
c ...... Didn't find kj, so a(k,kj) = 0, so bail out and get another j.
goto 30
c
c ...... Find ij such that ja(i,ij) = j. Whether one is found or
c not will determine whether to modify the diagonal or the
c off-diagonal.
20 continue
do ij=2,maxnz
if (ja(i,ij) .eq. 0) then
c
c ........ Out of elements, so a(i,ij) = 0, so bail out and modify
c diagonal.
goto 25
elseif (ja(i,ij) .eq. j) then
c
c ........ Found ij, so modify element a(i,ij).
a(i,ij) = a(i,ij) - a(i,kk)*a(k,kj)
goto 30
endif
enddo
c
c ...... Didn't find ij, so a(i,ij) = 0, so modify diagonal.
25 continue
a(i,1) = a(i,1) - a(i,kk)*a(k,kj)
30 continue
enddo ! end of loop over columns (j)
35 continue
enddo ! end of loop over rows (i)
enddo ! end of main loop (k)
a(n,1) = SQRT(a(n,1))
c
return
end