Factors a banded matrix by Gaussian elimination with partial pivoting.
The matrix A is stored in abd with A(i,j) in abd(i-j+ml+mu+1,j).
Rows 1:ml of abd are used for the fill-in generated by pivoting.
DGBFA (Cleve Moler, 1978).
Added the tol argument for detecting singular matrices.| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout), | dimension(2_ip*ml+mu+1_ip,n) | :: | abd |
IN: the matrix in band storage. OUT: its LU factorization. |
|
| integer(kind=ip), | intent(in) | :: | n |
order of the matrix |
||
| integer(kind=ip), | intent(in) | :: | ml |
number of diagonals below the main diagonal |
||
| integer(kind=ip), | intent(in) | :: | mu |
number of diagonals above the main diagonal |
||
| integer(kind=ip), | intent(out), | dimension(n) | :: | ipvt |
pivot indices |
|
| real(kind=wp), | intent(in) | :: | tol |
a pivot with |
||
| integer(kind=ip), | intent(out) | :: | info |
0 if successful, otherwise |
pure subroutine dgbfa(abd,n,ml,mu,ipvt,tol,info) implicit none integer(ip),intent(in) :: n !! order of the matrix integer(ip),intent(in) :: ml !! number of diagonals below the main diagonal integer(ip),intent(in) :: mu !! number of diagonals above the main diagonal real(wp),dimension(2_ip*ml+mu+1_ip,n),intent(inout) :: abd !! **IN:** the matrix in band storage. !! **OUT:** its LU factorization. integer(ip),dimension(n),intent(out) :: ipvt !! pivot indices real(wp),intent(in) :: tol !! a pivot with `abs(u(k,k)) <= tol` is !! treated as zero (`tol=0` gives the !! original LINPACK behavior) integer(ip),intent(out) :: info !! 0 if successful, otherwise `k` if `u(k,k)` !! is zero (the matrix is singular) integer(ip) :: i, j, jk, ju, jz, l, lm, m, mm real(wp) :: tmp m = ml + mu + 1_ip info = 0_ip ! zero the initial fill-in columns do jz = mu+2_ip, min(n,m)-1_ip abd(m+1_ip-jz:ml,jz) = 0.0_wp end do jz = min(n,m) - 1_ip ju = 0_ip do jk = 1_ip, n-1_ip ! zero the next fill-in column jz = jz + 1_ip if (jz<=n .and. ml>=1_ip) abd(1:ml,jz) = 0.0_wp ! find the pivot lm = min(ml,n-jk) l = maxloc(abs(abd(m:m+lm,jk)),dim=1,kind=ip) + m - 1_ip ipvt(jk) = l + jk - m if (abs(abd(l,jk))<=tol) then ! this column is already triangularized info = jk cycle end if ! interchange if necessary if (l/=m) then tmp = abd(l,jk) abd(l,jk) = abd(m,jk) abd(m,jk) = tmp end if ! compute the multipliers abd(m+1_ip:m+lm,jk) = abd(m+1_ip:m+lm,jk) * (-1.0_wp/abd(m,jk)) ! row elimination with column indexing ju = min(max(ju,mu+ipvt(jk)),n) mm = m do j = jk+1_ip, ju l = l - 1_ip mm = mm - 1_ip tmp = abd(l,j) if (l/=mm) then abd(l,j) = abd(mm,j) abd(mm,j) = tmp end if do i = 1_ip, lm abd(mm+i,j) = abd(mm+i,j) + tmp*abd(m+i,jk) end do end do end do ipvt(n) = n if (abs(abd(m,n))<=tol) info = n end subroutine dgbfa