Rev 6098 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
cc zhico factors a double complex hermitian matrix by elimination withc symmetric pivoting and estimates the condition of the matrix.cc if rcond is not needed, zhifa is slightly faster.c to solve a*x = b , follow zhico by zhisl.c to compute inverse(a)*c , follow zhico by zhisl.c to compute inverse(a) , follow zhico by zhidi.c to compute determinant(a) , follow zhico by zhidi.c to compute inertia(a), follow zhico 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 outputcc 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 rcond double precisionc an estimate of the reciprocal condition of a .c for the system a*x = b , relative perturbationsc in a and b of size epsilon may causec relative perturbations in x of size epsilon/rcond .c if rcond is so small that the logical expressionc 1.0 + rcond .eq. 1.0c is true, then a may be singular to workingc precision. in particular, rcond is zero ifc exact singularity is detected or the estimatec underflows.cc z double complex(n)c a work vector whose contents are usually unimportant.c if a is close to a singular matrix, then z isc an approximate null vector in the sense thatc norm(a*z) = rcond*norm(a)*norm(z) .cc linpack. this version dated 08/14/78 .c cleve moler, university of new mexico, argonne national lab.cc subroutines and functionscc linpack zhifac blas zaxpy,zdotc,zdscal,dzasumc fortran dabs,dmax1,dcmplx,dconjg,iabscsubroutine zhico(a,lda,n,kpvt,rcond,z)integer lda,n,kpvt(*)double complex a(lda,*),z(*)double precision rcondcc internal variablescdouble complex ak,akm1,bk,bkm1,zdotc,denom,ek,tdouble precision anorm,s,dzasum,ynorminteger i,info,j,jm1,k,kp,kps,kscdouble complex zdum,zdum2,csign1double precision cabs1double precision dreal,dimagdouble complex zdumr,zdumidreal(zdumr) = zdumrdimag(zdumi) = (0.0d0,-1.0d0)*zdumicabs1(zdum) = dabs(dreal(zdum)) + dabs(dimag(zdum))csign1(zdum,zdum2) = cabs1(zdum)*(zdum2/cabs1(zdum2))cc find norm of a using only upper halfcdo 30 j = 1, nz(j) = dcmplx(dzasum(j,a(1,j),1),0.0d0)jm1 = j - 1if (jm1 .lt. 1) go to 20do 10 i = 1, jm1z(i) = dcmplx(dreal(z(i))+cabs1(a(i,j)),0.0d0)10 continue20 continue30 continueanorm = 0.0d0do 40 j = 1, nanorm = dmax1(anorm,dreal(z(j)))40 continuecc factorccall zhifa(a,lda,n,kpvt,info)cc rcond = 1/(norm(a)*(estimate of norm(inverse(a)))) .c estimate = norm(z)/norm(y) where a*z = y and a*y = e .c the components of e are chosen to cause maximum localc growth in the elements of w where u*d*w = e .c the vectors are frequently rescaled to avoid overflow.cc solve u*d*w = ecek = (1.0d0,0.0d0)do 50 j = 1, nz(j) = (0.0d0,0.0d0)50 continuek = n60 if (k .eq. 0) go to 120ks = 1if (kpvt(k) .lt. 0) ks = 2kp = iabs(kpvt(k))kps = k + 1 - ksif (kp .eq. kps) go to 70t = z(kps)z(kps) = z(kp)z(kp) = t70 continueif (cabs1(z(k)) .ne. 0.0d0) ek = csign1(ek,z(k))z(k) = z(k) + ekcall zaxpy(k-ks,z(k),a(1,k),1,z(1),1)if (ks .eq. 1) go to 80if (cabs1(z(k-1)) .ne. 0.0d0) ek = csign1(ek,z(k-1))z(k-1) = z(k-1) + ekcall zaxpy(k-ks,z(k-1),a(1,k-1),1,z(1),1)80 continueif (ks .eq. 2) go to 100if (cabs1(z(k)) .le. cabs1(a(k,k))) go to 90s = cabs1(a(k,k))/cabs1(z(k))call zdscal(n,s,z,1)ek = dcmplx(s,0.0d0)*ek90 continueif (cabs1(a(k,k)) .ne. 0.0d0) z(k) = z(k)/a(k,k)if (cabs1(a(k,k)) .eq. 0.0d0) z(k) = (1.0d0,0.0d0)go to 110100 continueak = a(k,k)/dconjg(a(k-1,k))akm1 = a(k-1,k-1)/a(k-1,k)bk = z(k)/dconjg(a(k-1,k))bkm1 = z(k-1)/a(k-1,k)denom = ak*akm1 - 1.0d0z(k) = (akm1*bk - bkm1)/denomz(k-1) = (ak*bkm1 - bk)/denom110 continuek = k - ksgo to 60120 continues = 1.0d0/dzasum(n,z,1)call zdscal(n,s,z,1)cc solve ctrans(u)*y = wck = 1130 if (k .gt. n) go to 160ks = 1if (kpvt(k) .lt. 0) ks = 2if (k .eq. 1) go to 150z(k) = z(k) + zdotc(k-1,a(1,k),1,z(1),1)if (ks .eq. 2)* z(k+1) = z(k+1) + zdotc(k-1,a(1,k+1),1,z(1),1)kp = iabs(kpvt(k))if (kp .eq. k) go to 140t = z(k)z(k) = z(kp)z(kp) = t140 continue150 continuek = k + ksgo to 130160 continues = 1.0d0/dzasum(n,z,1)call zdscal(n,s,z,1)cynorm = 1.0d0cc solve u*d*v = yck = n170 if (k .eq. 0) go to 230ks = 1if (kpvt(k) .lt. 0) ks = 2if (k .eq. ks) go to 190kp = iabs(kpvt(k))kps = k + 1 - ksif (kp .eq. kps) go to 180t = z(kps)z(kps) = z(kp)z(kp) = t180 continuecall zaxpy(k-ks,z(k),a(1,k),1,z(1),1)if (ks .eq. 2) call zaxpy(k-ks,z(k-1),a(1,k-1),1,z(1),1)190 continueif (ks .eq. 2) go to 210if (cabs1(z(k)) .le. cabs1(a(k,k))) go to 200s = cabs1(a(k,k))/cabs1(z(k))call zdscal(n,s,z,1)ynorm = s*ynorm200 continueif (cabs1(a(k,k)) .ne. 0.0d0) z(k) = z(k)/a(k,k)if (cabs1(a(k,k)) .eq. 0.0d0) z(k) = (1.0d0,0.0d0)go to 220210 continueak = a(k,k)/dconjg(a(k-1,k))akm1 = a(k-1,k-1)/a(k-1,k)bk = z(k)/dconjg(a(k-1,k))bkm1 = z(k-1)/a(k-1,k)denom = ak*akm1 - 1.0d0z(k) = (akm1*bk - bkm1)/denomz(k-1) = (ak*bkm1 - bk)/denom220 continuek = k - ksgo to 170230 continues = 1.0d0/dzasum(n,z,1)call zdscal(n,s,z,1)ynorm = s*ynormcc solve ctrans(u)*z = vck = 1240 if (k .gt. n) go to 270ks = 1if (kpvt(k) .lt. 0) ks = 2if (k .eq. 1) go to 260z(k) = z(k) + zdotc(k-1,a(1,k),1,z(1),1)if (ks .eq. 2)* z(k+1) = z(k+1) + zdotc(k-1,a(1,k+1),1,z(1),1)kp = iabs(kpvt(k))if (kp .eq. k) go to 250t = z(k)z(k) = z(kp)z(kp) = t250 continue260 continuek = k + ksgo to 240270 continuec make znorm = 1.0s = 1.0d0/dzasum(n,z,1)call zdscal(n,s,z,1)ynorm = s*ynormcif (anorm .ne. 0.0d0) rcond = ynorm/anormif (anorm .eq. 0.0d0) rcond = 0.0d0returnend