subroutine sgesl (a, lda, n, ipvt, b, job) !***BEGIN PROLOGUE SGESL !***PURPOSE Solve the real system A*X=B or TRANS(A)*X=B using the ! factors of SGECO or SGEFA. !***CATEGORY D2A1 !***TYPE SINGLE PRECISION (SGESL-S, DGESL-D, CGESL-C) !***KEYWORDS LINEAR ALGEBRA, LINPACK, MATRIX, SOLVE !***AUTHOR Moler, C. B., (U. of New Mexico) !***DESCRIPTION ! ! SGESL solves the real system ! A * X = B or TRANS(A) * X = B ! using the factors computed by SGECO or SGEFA. ! ! On Entry ! ! a real(lda, n) ! the output from sgeco or sgefa. ! ! lda integer ! the leading dimension of the array a . ! ! n integer ! the order of the matrix a . ! ! ipvt integer(n) ! the pivot vector from sgeco or sgefa. ! ! b real(n) ! the right hand side vector. ! ! job integer ! = 0 to solve a*x = b , ! = nonzero to solve trans(a)*x = b where ! trans(a) is the transpose. ! ! On Return ! ! b the solution vector x . ! ! Error Condition ! ! A division by zero will occur if the input factor contains a ! zero on the diagonal. Technically, this indicates singularity, ! but it is often caused by improper arguments or improper ! setting of LDA . It will not occur if the subroutines are ! called correctly and if SGECO has set RCOND .GT. 0.0 ! or SGEFA has set INFO .EQ. 0 . ! ! To compute INVERSE(A) * C where C is a matrix ! with P columns ! CALL SGECO(A,LDA,N,IPVT,RCOND,Z) ! IF (RCOND is too small) GO TO ... ! DO 10 J = 1, P ! CALL SGESL(A,LDA,N,IPVT,C(1,J),0) ! 10 CONTINUE ! !***REFERENCES J. J. Dongarra, J. R. Bunch, C. B. Moler, and G. W. ! Stewart, LINPACK Users' Guide, SIAM, 1979. !***ROUTINES CALLED SAXPY, SDOT !***REVISION HISTORY (YYMMDD) ! 780814 DATE WRITTEN ! 890831 Modified array declarations. (WRB) ! 890831 REVISION DATE from Version 3.2 ! 891214 Prologue converted to Version 4.0 format. (BAB) ! 900326 Removed duplicate information from DESCRIPTION section. ! (WRB) ! 920501 Reformatted the REFERENCES section. (WRB) !***END PROLOGUE SGESL integer lda,n,ipvt(*),job real a(lda,*),b(*) ! real sdot,t integer k,kb,l,nm1 !***first executable statement sgesl nm1 = n - 1 if (job .ne. 0) go to 50 ! ! job = 0 , solve a * x = b ! first solve l*y = b ! if (nm1 .lt. 1) go to 30 do 20 k = 1, nm1 l = ipvt(k) t = b(l) if (l .eq. k) go to 10 b(l) = b(k) b(k) = t 10 continue call saxpy(n-k,t,a(k+1,k),1,b(k+1),1) 20 continue 30 continue ! ! now solve u*x = y ! do 40 kb = 1, n k = n + 1 - kb b(k) = b(k)/a(k,k) t = -b(k) call saxpy(k-1,t,a(1,k),1,b(1),1) 40 continue go to 100 50 continue ! ! job = nonzero, solve trans(a) * x = b ! first solve trans(u)*y = b ! do 60 k = 1, n t = sdot(k-1,a(1,k),1,b(1),1) b(k) = (b(k) - t)/a(k,k) 60 continue ! ! now solve trans(l)*x = y ! if (nm1 .lt. 1) go to 90 do 80 kb = 1, nm1 k = n - kb b(k) = b(k) + sdot(n-k,a(k+1,k),1,b(k+1),1) l = ipvt(k) if (l .eq. k) go to 70 t = b(l) b(l) = b(k) b(k) = t 70 continue 80 continue 90 continue 100 continue return end