solve the real system a*x=b
or trans(a)*x=b
using the
factors computed by dgeco or dgefa.
to compute inverse(a) * c
where c
is a matrix
with p
columns:
call dgeco(a,lda,n,ipvt,rcond,z)
if (rcond is too small) go to ...
do j = 1, p
call dgesl(a,lda,n,ipvt,c(1,j),0)
end do
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 dgeco has set rcond > 0.0 or dgefa has set info == 0 .
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | a(lda,*) | |||
integer, | intent(in) | :: | lda |
the leading dimension of the array |
||
integer, | intent(in) | :: | n |
the order of the matrix |
||
integer, | intent(in) | :: | ipvt(*) | |||
real(kind=wp), | intent(out) | :: | b(*) |
the solution vector |
||
integer, | intent(in) | :: | job |
|
subroutine dgesl(a,lda,n,ipvt,b,job) integer,intent(in) :: lda !! the leading dimension of the array `a`. integer,intent(in) :: n !! the order of the matrix `a`. integer,intent(in) :: ipvt(*) !! the pivot vector from [[dgeco]] or [[dgefa]]. integer,intent(in) :: job !! * 0 to solve `a*x = b` , !! * nonzero to solve `trans(a)*x = b` where !! `trans(a)` is the transpose. real(wp),intent(in) :: a(lda,*) !! `(lda, n)` the output from [[dgeco]] or [[dgefa]]. real(wp),intent(out) :: b(*) !! the solution vector `x`. real(wp) :: t integer :: k , kb , l , nm1 #ifdef HAS_BLAS ! user is linking against an external BLAS library double precision,external :: ddot #endif nm1 = n - 1 if ( job/=0 ) then ! job = nonzero, solve trans(a) * x = b ! first solve trans(u)*y = b do k = 1 , n t = ddot(k-1,a(1,k),1,b(1),1) b(k) = (b(k)-t)/a(k,k) enddo ! now solve trans(l)*x = y if ( nm1>=1 ) then do kb = 1 , nm1 k = n - kb b(k) = b(k) + ddot(n-k,a(k+1,k),1,b(k+1),1) l = ipvt(k) if ( l/=k ) then t = b(l) b(l) = b(k) b(k) = t endif enddo endif else ! job = 0 , solve a * x = b ! first solve l*y = b if ( nm1>=1 ) then do k = 1 , nm1 l = ipvt(k) t = b(l) if ( l/=k ) then b(l) = b(k) b(k) = t endif call daxpy(n-k,t,a(k+1,k),1,b(k+1),1) enddo endif ! now solve u*x = y do kb = 1 , n k = n + 1 - kb b(k) = b(k)/a(k,k) t = -b(k) call daxpy(k-1,t,a(1,k),1,b(1),1) enddo endif end subroutine dgesl