fctr Subroutine

public pure subroutine fctr(oksemi, a, lda, n, info)

Uses

  • proc~~fctr~~UsesGraph proc~fctr fctr module~odrpack_kinds odrpack_kinds proc~fctr->module~odrpack_kinds iso_fortran_env iso_fortran_env module~odrpack_kinds->iso_fortran_env

Factor the positive (semi)definite matrix a using a modified Cholesky factorization.

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: oksemi

Flag indicating whether the factored array can be positive semidefinite (.true.) or whether it must be found to be positive definite (.false.).

real(kind=wp), intent(inout) :: a(lda,n)

Array to be factored. Upon return, a contains the upper triangular matrix r so that a = trans(r)*r where the strict lower triangle is set to zero. If info /= 0, the factorization is not complete.

integer, intent(in) :: lda

Leading dimension of array a.

integer, intent(in) :: n

Number of rows and columns of data in array a.

integer, intent(out) :: info

Output flag. 0: Factorization was completed. k: Error condition. The leading minor of order k is not positive (semi)definite.


Called by

proc~~fctr~~CalledByGraph proc~fctr fctr proc~fctrw fctrw proc~fctrw->proc~fctr proc~lcstep lcstep proc~lcstep->proc~fctr proc~odr odr proc~odr->proc~fctrw proc~trust_region trust_region proc~odr->proc~trust_region proc~vcv_beta vcv_beta proc~odr->proc~vcv_beta proc~trust_region->proc~lcstep proc~vcv_beta->proc~lcstep proc~odr_long_c odr_long_c proc~odr_long_c->proc~odr proc~odr_medium_c odr_medium_c proc~odr_medium_c->proc~odr proc~odr_short_c odr_short_c proc~odr_short_c->proc~odr program~example1 example1 program~example1->proc~odr program~example2 example2 program~example2->proc~odr program~example3 example3 program~example3->proc~odr program~example4 example4 program~example4->proc~odr program~example5 example5 program~example5->proc~odr

Variables

Type Visibility Attributes Name Initial
real(kind=wp), public :: xi
real(kind=wp), public :: s
real(kind=wp), public :: t
integer, public :: j
integer, public :: k

Source Code

   pure subroutine fctr(oksemi, a, lda, n, info)
   !! Factor the positive (semi)definite matrix `a` using a modified Cholesky factorization.
      ! Adapted from LINPACK subroutine DPOFA.

      use odrpack_kinds, only: zero

      logical, intent(in) :: oksemi
         !! Flag indicating whether the factored array can be positive semidefinite
         !! (`.true.`) or whether it must be found to be positive definite (`.false.`).
      real(wp), intent(inout) :: a(lda, n)
         !! Array to be factored. Upon return, `a` contains the upper triangular matrix
         !! `r` so that `a = trans(r)*r` where the strict lower triangle is set to zero.
         !! If `info /= 0`, the factorization is not complete.
      integer, intent(in) :: lda
         !! Leading dimension of array `a`.
      integer, intent(in) :: n
         !! Number of rows and columns of data in array `a`.
      integer, intent(out) :: info
         !! Output flag.
         !! `0`: Factorization was completed.
         !! `k`: Error condition. The leading minor of order `k` is not positive (semi)definite.

      ! Local scalars
      real(wp) :: xi, s, t
      integer j, k

      ! Variable Definitions (alphabetically)
      !  J:       An indexing variable.
      !  K:       An indexing variable.
      !  XI:      A value used to test for non positive semidefiniteness.

      ! Set relative tolerance for detecting non positive semidefiniteness.
      xi = -10*epsilon(zero)

      ! Compute factorization, storing in upper triangular portion of A
      do j = 1, n
         info = j
         s = zero
         do k = 1, j - 1
            if (a(k, k) == zero) then
               t = zero
            else
               t = a(k, j) - dot_product(a(1:k - 1, k), a(1:k - 1, j))
               t = t/a(k, k)
            end if
            a(k, j) = t
            s = s + t**2
         end do
         s = a(j, j) - s

         ! Exit
         if (a(j, j) < zero .or. s < xi*abs(a(j, j))) then
            return
         elseif (.not. oksemi .and. s <= zero) then
            return
         elseif (s <= zero) then
            a(j, j) = zero
         else
            a(j, j) = sqrt(s)
         end if
      end do
      info = 0

      ! Zero out lower portion of A
      do j = 1, n - 1
         a(j + 1:n, j) = zero
      end do

   end subroutine fctr