Rev 76286 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
cc dpodi computes the determinant and inverse of a certainc double precision symmetric positive definite matrix (see below)c using the factors computed by dpoco, dpofa or dqrdc.cc on entrycc a double precision(lda, n)c the output a from dpoco or dpofac or the output x from dqrdc.cc lda integerc the leading dimension of the array a .cc n integerc the order of the matrix a .cc job integerc = 11 both determinant and inverse.c = 01 inverse only.c = 10 determinant only.cc on returncc a if dpoco or dpofa was used to factor a thenc dpodi produces the upper half of inverse(a) .c if dqrdc was used to decompose x thenc dpodi produces the upper half of inverse(trans(x)*x)c where trans(x) is the transpose.c elements of a below the diagonal are unchanged.c if the units digit of job is zero, a is unchanged.cc det double precision(2)c determinant of a or of trans(x)*x if requested.c otherwise not referenced.c determinant = det(1) * 10.0**det(2)c with 1.0 .le. det(1) .lt. 10.0c or det(1) .eq. 0.0 .cc error conditioncc a division by zero will occur if the input factor containsc a zero on the diagonal and the inverse is requested.c it will not occur if the subroutines are called correctlyc and if dpoco or dpofa has set info .eq. 0 .cc linpack. this version dated 08/14/78 .c cleve moler, university of new mexico, argonne national lab.cc subroutines and functionscc blas daxpy,dscalc fortran modcsubroutine dpodi(a,lda,n,det,job)integer lda,n,jobdouble precision a(lda,n)double precision det(2)cc internal variablescdouble precision tdouble precision sinteger i,j,jm1,k,kp1cc compute determinantcif (job/10 .eq. 0) go to 70det(1) = 1.0d0det(2) = 0.0d0s = 10.0d0do 50 i = 1, ndet(1) = a(i,i)**2*det(1)c ...exitif (det(1) .eq. 0.0d0) go to 6010 if (det(1) .ge. 1.0d0) go to 20det(1) = s*det(1)det(2) = det(2) - 1.0d0go to 1020 continue30 if (det(1) .lt. s) go to 40det(1) = det(1)/sdet(2) = det(2) + 1.0d0go to 3040 continue50 continue60 continue70 continuecc compute inverse(r)cif (mod(job,10) .eq. 0) go to 140do 100 k = 1, na(k,k) = 1.0d0/a(k,k)t = -a(k,k)call dscal(k-1,t,a(1,k),1)kp1 = k + 1if (n .lt. kp1) go to 90do 80 j = kp1, nt = a(k,j)a(k,j) = 0.0d0call daxpy(k,t,a(1,k),1,a(1,j),1)80 continue90 continue100 continuecc form inverse(r) * trans(inverse(r))cdo 130 j = 1, njm1 = j - 1if (jm1 .lt. 1) go to 120do 110 k = 1, jm1t = a(k,j)call daxpy(k,t,a(1,j),1,a(1,k),1)110 continue120 continuet = a(j,j)call dscal(j,t,a(1,j),1)130 continue140 continuereturnend