Rev 5457 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
subroutine dtrco(t,ldt,n,rcond,z,job)integer ldt,n,jobdouble precision t(ldt,*),z(*)double precision rcondcc dtrco estimates the condition of a double precision triangularc matrix.cc on entrycc t double precision(ldt,n)c t contains the triangular matrix. the zeroc elements of the matrix are not referenced, andc the corresponding elements of the array can bec used to store other information.cc ldt integerc ldt is the leading dimension of the array t.cc n integerc n is the order of the system.cc job integerc = 0 t is lower triangular.c = nonzero t is upper triangular.cc on returncc rcond double precisionc an estimate of the reciprocal condition of t .c for the system t*x = b , relative perturbationsc in t 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 t may be singular to workingc precision. in particular, rcond is zero ifc exact singularity is detected or the estimatec underflows.cc z double precision(n)c a work vector whose contents are usually unimportant.c if t 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 blas daxpy,dscal,dasumc fortran dabs,dmax1,dsigncc internal variablescdouble precision w,wk,wkm,ekdouble precision tnorm,ynorm,s,sm,dasuminteger i1,j,j1,j2,k,kk,llogical lowerclower = job .eq. 0cc compute 1-norm of tctnorm = 0.0d0do 10 j = 1, nl = jif (lower) l = n + 1 - ji1 = 1if (lower) i1 = jtnorm = dmax1(tnorm,dasum(l,t(i1,j),1))10 continuecc rcond = 1/(norm(t)*(estimate of norm(inverse(t)))) .c estimate = norm(z)/norm(y) where t*z = y and trans(t)*y = e .c trans(t) is the transpose of t .c the components of e are chosen to cause maximum localc growth in the elements of y .c the vectors are frequently rescaled to avoid overflow.cc solve trans(t)*y = ecek = 1.0d0do 20 j = 1, nz(j) = 0.0d020 continuedo 100 kk = 1, nk = kkif (lower) k = n + 1 - kkif (z(k) .ne. 0.0d0) ek = dsign(ek,-z(k))if (dabs(ek-z(k)) .le. dabs(t(k,k))) go to 30s = dabs(t(k,k))/dabs(ek-z(k))call dscal(n,s,z,1)ek = s*ek30 continuewk = ek - z(k)wkm = -ek - z(k)s = dabs(wk)sm = dabs(wkm)if (t(k,k) .eq. 0.0d0) go to 40wk = wk/t(k,k)wkm = wkm/t(k,k)go to 5040 continuewk = 1.0d0wkm = 1.0d050 continueif (kk .eq. n) go to 90j1 = k + 1if (lower) j1 = 1j2 = nif (lower) j2 = k - 1do 60 j = j1, j2sm = sm + dabs(z(j)+wkm*t(k,j))z(j) = z(j) + wk*t(k,j)s = s + dabs(z(j))60 continueif (s .ge. sm) go to 80w = wkm - wkwk = wkmdo 70 j = j1, j2z(j) = z(j) + w*t(k,j)70 continue80 continue90 continuez(k) = wk100 continues = 1.0d0/dasum(n,z,1)call dscal(n,s,z,1)cynorm = 1.0d0cc solve t*z = ycdo 130 kk = 1, nk = n + 1 - kkif (lower) k = kkif (dabs(z(k)) .le. dabs(t(k,k))) go to 110s = dabs(t(k,k))/dabs(z(k))call dscal(n,s,z,1)ynorm = s*ynorm110 continueif (t(k,k) .ne. 0.0d0) z(k) = z(k)/t(k,k)if (t(k,k) .eq. 0.0d0) z(k) = 1.0d0i1 = 1if (lower) i1 = k + 1if (kk .ge. n) go to 120w = -z(k)call daxpy(n-kk,w,t(i1,k),1,z(i1),1)120 continue130 continuec make znorm = 1.0s = 1.0d0/dasum(n,z,1)call dscal(n,s,z,1)ynorm = s*ynormcif (tnorm .ne. 0.0d0) rcond = ynorm/tnormif (tnorm .eq. 0.0d0) rcond = 0.0d0returnend