! !$Author$ !$Date$ !$Revision$ !$HeadURL$ ! subroutine sgbsl (abd, lda, n, ml, mu, ipvt, b, job) !***BEGIN PROLOGUE SGBSL !***PURPOSE Solve the real band system A*X=B or TRANS(A)*X=B using ! the factors computed by SGBCO or SGBFA. !***CATEGORY D2A2 !***TYPE SINGLE PRECISION (SGBSL-S, DGBSL-D, CGBSL-C) !***KEYWORDS BANDED, LINEAR ALGEBRA, LINPACK, MATRIX, SOLVE !***AUTHOR Moler, C. B., (U. of New Mexico) !***DESCRIPTION ! ! SGBSL solves the real band system ! A * X = B or TRANS(A) * X = B ! using the factors computed by SBGCO or SGBFA. ! ! On Entry ! ! abd real(lda, n) ! the output from sbgco or sgbfa. ! ! lda integer ! the leading dimension of the array abd . ! ! n integer ! the order of the original matrix. ! ! ml integer ! number of diagonals below the main diagonal. ! ! mu integer ! number of diagonals above the main diagonal. ! ! ipvt integer(n) ! the pivot vector from sbgco or sgbfa. ! ! 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 SBGCO has set RCOND .GT. 0.0 ! or SGBFA has set INFO .EQ. 0 . ! ! To compute INVERSE(A) * C where C is a matrix ! with P columns ! CALL SBGCO(ABD,LDA,N,ML,MU,IPVT,RCOND,Z) ! If (RCOND is too small) GO TO ... ! DO 10 J = 1, P ! CALL SGBSL(ABD,LDA,N,ML,MU,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 ! 890531 Changed all specific intrinsics to generic. (WRB) ! 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 SGBSL integer lda,n,ml,mu,ipvt(*),job real abd(lda,*),b(*) ! real sdot,t integer k,kb,l,la,lb,lm,m,nm1 !***first executable statement sgbsl m = mu + ml + 1 nm1 = n - 1 if (job .ne. 0) go to 50 ! ! job = 0 , solve a * x = b ! first solve l*y = b ! if (ml .eq. 0) go to 30 if (nm1 .lt. 1) go to 30 do 20 k = 1, nm1 lm = min(ml,n-k) l = ipvt(k) t = b(l) if (l .eq. k) go to 10 b(l) = b(k) b(k) = t 10 continue call saxpy(lm,t,abd(m+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)/abd(m,k) lm = min(k,m) - 1 la = m - lm lb = k - lm t = -b(k) call saxpy(lm,t,abd(la,k),1,b(lb),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 lm = min(k,m) - 1 la = m - lm lb = k - lm t = sdot(lm,abd(la,k),1,b(lb),1) b(k) = (b(k) - t)/abd(m,k) 60 continue ! ! now solve trans(l)*x = y ! if (ml .eq. 0) go to 90 if (nm1 .lt. 1) go to 90 do 80 kb = 1, nm1 k = n - kb lm = min(ml,n-k) b(k) = b(k) + sdot(lm,abd(m+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