NAFPack_matrix_tools.f90 Source File


This file depends on

sourcefile~~nafpack_matrix_tools.f90~~EfferentGraph sourcefile~nafpack_matrix_tools.f90 NAFPack_matrix_tools.f90 sourcefile~nafpack_kinds.f90 NAFPack_kinds.f90 sourcefile~nafpack_matrix_tools.f90->sourcefile~nafpack_kinds.f90 sourcefile~nafpack_matricielle.f90 NAFPack_matricielle.f90 sourcefile~nafpack_matrix_tools.f90->sourcefile~nafpack_matricielle.f90 sourcefile~nafpack_matricielle.f90->sourcefile~nafpack_kinds.f90

Files dependent on this one

sourcefile~~nafpack_matrix_tools.f90~~AfferentGraph sourcefile~nafpack_matrix_tools.f90 NAFPack_matrix_tools.f90 sourcefile~nafpack_direct_methode.f90 NAFPack_Direct_methode.f90 sourcefile~nafpack_direct_methode.f90->sourcefile~nafpack_matrix_tools.f90 sourcefile~nafpack_linalg.f90 NAFPack_linalg.f90 sourcefile~nafpack_linalg.f90->sourcefile~nafpack_direct_methode.f90

Source Code

module NAFPack_matrix_tools

    use NAFPack_kinds, only: dp
    use NAFPack_matricielle, only: Identity_n, Trace

    implicit none(type, external)

    private
    public :: Faddeev_Leverrier

contains

    subroutine Faddeev_Leverrier(A, c, Ainv, success, check)
        integer, parameter :: dp = kind(1.0d0)
        real(dp), dimension(:, :), intent(in) :: A
        logical, optional, intent(in) :: check
        real(dp), dimension(:), intent(out) :: c
        real(dp), dimension(size(A, 1), size(A, 1)), optional, intent(out) :: Ainv
        logical, optional, intent(out) :: success
        real(dp), dimension(size(A, 1), size(A, 1)) :: Bk, I, B_Nm1, AB
        logical :: do_check
        integer :: N, k

        N = size(A, 1)
        do_check = .true.

        if (present(check)) do_check = check

        if (do_check) then
            print*,"Checking if the matrix A is square and size of c is correct"
            if (size(A, 2) /= N .or. size(c) < N + 1) then
                print*,"Error : Matrix A must be square and size of c must be at least N+1"
                stop
            end if
        end if

        ! Initialization
        I = Identity_n(N)
        c = 0.0_dp
        c(1) = 1.0_dp
        c(2) = -Trace(A)
        Bk = A + c(2) * I

        do k = 2, N
            AB = matmul(A, Bk)
            c(k + 1) = -Trace(AB) / real(k, dp)
            Bk = AB + c(k + 1) * I
            if (k == N - 1 .and. present(Ainv)) B_Nm1 = -Bk
        end do

        if (present(Ainv) .and. present(success)) then
            if (abs(c(N + 1)) < 1.0e-12_dp) then
                success = .false.
                Ainv = 0.0_dp
            else
                success = .true.
                Ainv = B_Nm1 / c(N + 1)
            end if
        else if (present(Ainv)) then
            if (abs(c(N + 1)) < 1.0e-12_dp) then
                Ainv = 0.0_dp
            else
                Ainv = B_Nm1 / c(N + 1)
            end if
        end if

    end subroutine Faddeev_Leverrier

end module NAFPack_matrix_tools