!>
!> @file dtblok.f90
!>
!> @brief
!>
!> @copyright
!> Copyright (©) 2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
!> SPC (Swiss Plasma Center)
!>
!> SPClibs is free software: you can redistribute it and/or modify it under
!> the terms of the GNU Lesser General Public License as published by the Free
!> Software Foundation, either version 3 of the License, or (at your option)
!> any later version.
!>
!> SPClibs is distributed in the hope that it will be useful, but WITHOUT ANY
!> WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
!> FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
!>
!> You should have received a copy of the GNU Lesser General Public License
!> along with this program. If not, see .
!>
!> @authors
!> (in alphabetical order)
!> @author Trach-Minh Tran
!>
subroutine dtblok ( bloks, integs, nbloks, ipivot, iflag, detsgn, detlog )
!*************************************************************************
!
!! DTBLOK gets the determinant of an almost block diagonal matrix.
!
! Discussion:
!
! The matrix's PLU factorization must have been obtained
! previously by FCBLOK.
!
! The logarithm of the determinant is computed instead of the
! determinant itself to avoid the danger of overflow or underflow
! inherent in this calculation.
!
! Reference:
!
! Carl DeBoor,
! A Practical Guide to Splines,
! Springer Verlag.
!
! Parameters:
!
! bloks, integs, nbloks, ipivot, iflag are as on return from fcblok.
! in particular, iflag=(-1)**(number of interchanges dur-
! ing factorization) if successful, otherwise iflag=0.
!
! detsgn on output, contains the sign of the determinant.
!
! detlog on output, contains the natural logarithm of the determi-
! nant if determinant is not zero. otherwise contains 0.
!
implicit none
integer nbloks
real ( kind = 8 ) bloks(1)
real ( kind = 8 ) detlog
real ( kind = 8 ) detsgn
integer i
integer iflag
integer index
integer indexp
integer integs(3,nbloks)
integer ip
integer ipivot(1)
integer k
integer last
integer nrow
detsgn = iflag
detlog = 0.0D+00
if ( iflag == 0 ) then
return
end if
index = 0
indexp = 0
do i = 1, nbloks
nrow = integs(1,i)
last = integs(3,i)
do k = 1, last
ip = index + nrow * (k-1) + ipivot(indexp+k)
detlog = detlog + log ( abs ( bloks(ip) ) )
detsgn = detsgn * sign ( 1.0D+00, bloks(ip) )
end do
index = nrow*integs(2,i)+index
indexp = indexp+nrow
end do
return
end