Rev 6098 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
cc zhifa factors a double complex hermitian matrix by eliminationc with symmetric pivoting.cc to solve a*x = b , follow zhifa by zhisl.c to compute inverse(a)*c , follow zhifa by zhisl.c to compute determinant(a) , follow zhifa by zhidi.c to compute inertia(a) , follow zhifa by zhidi.c to compute inverse(a) , follow zhifa by zhidi.cc on entrycc a double complex(lda,n)c the hermitian matrix to be factored.c only the diagonal and upper triangle are used.cc lda integerc the leading dimension of the array a .cc n integerc the order of the matrix a .cc on returncc a a block diagonal matrix and the multipliers whichc were used to obtain it.c the factorization can be written a = u*d*ctrans(u)c where u is a product of permutation and unitc upper triangular matrices , ctrans(u) is thec conjugate transpose of u , and d is block diagonalc with 1 by 1 and 2 by 2 blocks.cc kpvt integer(n)c an integer vector of pivot indices.cc info integerc = 0 normal value.c = k if the k-th pivot block is singular. this isc not an error condition for this subroutine,c but it does indicate that zhisl or zhidi mayc divide by zero if called.cc linpack. this version dated 08/14/78 .c james bunch, univ. calif. san diego, argonne nat. lab.cc subroutines and functionscc blas zaxpy,zswap,izamaxc fortran dabs,dmax1,dcmplx,dconjg,dsqrtcsubroutine zhifa(a,lda,n,kpvt,info)integer lda,n,kpvt(*),infodouble complex a(lda,*)cc internal variablescdouble complex ak,akm1,bk,bkm1,denom,mulk,mulkm1,tdouble precision absakk,alpha,colmax,rowmaxinteger imax,imaxp1,j,jj,jmax,k,km1,km2,kstep,izamaxlogical swapcdouble complex zdumdouble precision cabs1double precision dreal,dimagdouble complex zdumr,zdumidreal(zdumr) = zdumrdimag(zdumi) = (0.0d0,-1.0d0)*zdumicabs1(zdum) = dabs(dreal(zdum)) + dabs(dimag(zdum))cc initializecc alpha is used in choosing pivot block size.alpha = (1.0d0 + dsqrt(17.0d0))/8.0d0cinfo = 0cc main loop on k, which goes from n to 1.ck = n10 continuecc leave the loop if k=0 or k=1.cc ...exitif (k .eq. 0) go to 200if (k .gt. 1) go to 20kpvt(1) = 1if (cabs1(a(1,1)) .eq. 0.0d0) info = 1c ......exitgo to 20020 continuecc this section of code determines the kind ofc elimination to be performed. when it is completed,c kstep will be set to the size of the pivot block, andc swap will be set to .true. if an interchange isc required.ckm1 = k - 1absakk = cabs1(a(k,k))cc determine the largest off-diagonal element inc column k.cimax = izamax(k-1,a(1,k),1)colmax = cabs1(a(imax,k))if (absakk .lt. alpha*colmax) go to 30kstep = 1swap = .false.go to 9030 continuecc determine the largest off-diagonal element inc row imax.crowmax = 0.0d0imaxp1 = imax + 1do 40 j = imaxp1, krowmax = dmax1(rowmax,cabs1(a(imax,j)))40 continueif (imax .eq. 1) go to 50jmax = izamax(imax-1,a(1,imax),1)rowmax = dmax1(rowmax,cabs1(a(jmax,imax)))50 continueif (cabs1(a(imax,imax)) .lt. alpha*rowmax) go to 60kstep = 1swap = .true.go to 8060 continueif (absakk .lt. alpha*colmax*(colmax/rowmax)) go to 70kstep = 1swap = .false.go to 8070 continuekstep = 2swap = imax .ne. km180 continue90 continueif (dmax1(absakk,colmax) .ne. 0.0d0) go to 100cc column k is zero. set info and iterate the loop.ckpvt(k) = kinfo = kgo to 190100 continueif (kstep .eq. 2) go to 140cc 1 x 1 pivot block.cif (.not.swap) go to 120cc perform an interchange.ccall zswap(imax,a(1,imax),1,a(1,k),1)do 110 jj = imax, kj = k + imax - jjt = dconjg(a(j,k))a(j,k) = dconjg(a(imax,j))a(imax,j) = t110 continue120 continuecc perform the elimination.cdo 130 jj = 1, km1j = k - jjmulk = -a(j,k)/a(k,k)t = dconjg(mulk)call zaxpy(j,t,a(1,k),1,a(1,j),1)a(j,j) = dcmplx(dreal(a(j,j)),0.0d0)a(j,k) = mulk130 continuecc set the pivot array.ckpvt(k) = kif (swap) kpvt(k) = imaxgo to 190140 continuecc 2 x 2 pivot block.cif (.not.swap) go to 160cc perform an interchange.ccall zswap(imax,a(1,imax),1,a(1,k-1),1)do 150 jj = imax, km1j = km1 + imax - jjt = dconjg(a(j,k-1))a(j,k-1) = dconjg(a(imax,j))a(imax,j) = t150 continuet = a(k-1,k)a(k-1,k) = a(imax,k)a(imax,k) = t160 continuecc perform the elimination.ckm2 = k - 2if (km2 .eq. 0) go to 180ak = a(k,k)/a(k-1,k)akm1 = a(k-1,k-1)/dconjg(a(k-1,k))denom = 1.0d0 - ak*akm1do 170 jj = 1, km2j = km1 - jjbk = a(j,k)/a(k-1,k)bkm1 = a(j,k-1)/dconjg(a(k-1,k))mulk = (akm1*bk - bkm1)/denommulkm1 = (ak*bkm1 - bk)/denomt = dconjg(mulk)call zaxpy(j,t,a(1,k),1,a(1,j),1)t = dconjg(mulkm1)call zaxpy(j,t,a(1,k-1),1,a(1,j),1)a(j,k) = mulka(j,k-1) = mulkm1a(j,j) = dcmplx(dreal(a(j,j)),0.0d0)170 continue180 continuecc set the pivot array.ckpvt(k) = 1 - kif (swap) kpvt(k) = -imaxkpvt(k-1) = kpvt(k)190 continuek = k - kstepgo to 10200 continuereturnend