!> !> @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