submodule (lightkrylov_basekrylov) gram_schmidt_process implicit none contains !-------------------------------------------- !----- DOUBLE GRAM-SCHMIDT STEP ----- !-------------------------------------------- module procedure DGS_vector_against_basis_rsp character(len=*), parameter :: this_procedure = 'DGS_vector_against_basis_rsp' logical :: chk_X_orthonormality real(sp), dimension(size(X)) :: proj_coefficients, wrk ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! if (time_lightkrylov()) call timer%start(this_procedure) info = 0 proj_coefficients = zero_rsp; wrk = zero_rsp ! Orthogonalize vector y w.r.t. to Krylov basis X in two passes of GS. ! first pass call orthogonalize_against_basis(y, X, info, if_chk_orthonormal=.false., beta=proj_coefficients) call check_info(info, 'orthogonalize_against_basis_p1', this_module, this_procedure//', pass 1') ! second pass call orthogonalize_against_basis(y, X, info, if_chk_orthonormal=.false., beta=wrk) call check_info(info, 'orthogonalize_against_basis_p2', this_module, this_procedure//', pass 2') ! combine passes proj_coefficients = proj_coefficients + wrk if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure DGS_basis_against_basis_rsp character(len=*), parameter :: this_procedure = 'DGS_basis_against_basis_rsp' logical :: chk_X_orthonormality real(sp), dimension(size(X),size(Y)) :: proj_coefficients, wrk ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! if (time_lightkrylov()) call timer%start(this_procedure) info = 0 proj_coefficients = zero_rsp; wrk = zero_rsp ! Orthogonalize Krylov basis Y w.r.t. to Krylov basis X in two passes of GS. ! first pass call orthogonalize_against_basis(Y, X, info, if_chk_orthonormal=.false., beta=proj_coefficients) call check_info(info, 'orthogonalize_against_basis_p1', this_module, this_procedure//', first pass') ! second pass call orthogonalize_against_basis(Y, X, info, if_chk_orthonormal=.false., beta=wrk) call check_info(info, 'orthogonalize_against_basis_p2', this_module, this_procedure//', second pass') ! combine passes proj_coefficients = proj_coefficients + wrk if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure DGS_vector_against_basis_rdp character(len=*), parameter :: this_procedure = 'DGS_vector_against_basis_rdp' logical :: chk_X_orthonormality real(dp), dimension(size(X)) :: proj_coefficients, wrk ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! if (time_lightkrylov()) call timer%start(this_procedure) info = 0 proj_coefficients = zero_rdp; wrk = zero_rdp ! Orthogonalize vector y w.r.t. to Krylov basis X in two passes of GS. ! first pass call orthogonalize_against_basis(y, X, info, if_chk_orthonormal=.false., beta=proj_coefficients) call check_info(info, 'orthogonalize_against_basis_p1', this_module, this_procedure//', pass 1') ! second pass call orthogonalize_against_basis(y, X, info, if_chk_orthonormal=.false., beta=wrk) call check_info(info, 'orthogonalize_against_basis_p2', this_module, this_procedure//', pass 2') ! combine passes proj_coefficients = proj_coefficients + wrk if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure DGS_basis_against_basis_rdp character(len=*), parameter :: this_procedure = 'DGS_basis_against_basis_rdp' logical :: chk_X_orthonormality real(dp), dimension(size(X),size(Y)) :: proj_coefficients, wrk ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! if (time_lightkrylov()) call timer%start(this_procedure) info = 0 proj_coefficients = zero_rdp; wrk = zero_rdp ! Orthogonalize Krylov basis Y w.r.t. to Krylov basis X in two passes of GS. ! first pass call orthogonalize_against_basis(Y, X, info, if_chk_orthonormal=.false., beta=proj_coefficients) call check_info(info, 'orthogonalize_against_basis_p1', this_module, this_procedure//', first pass') ! second pass call orthogonalize_against_basis(Y, X, info, if_chk_orthonormal=.false., beta=wrk) call check_info(info, 'orthogonalize_against_basis_p2', this_module, this_procedure//', second pass') ! combine passes proj_coefficients = proj_coefficients + wrk if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure DGS_vector_against_basis_csp character(len=*), parameter :: this_procedure = 'DGS_vector_against_basis_csp' logical :: chk_X_orthonormality complex(sp), dimension(size(X)) :: proj_coefficients, wrk ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! if (time_lightkrylov()) call timer%start(this_procedure) info = 0 proj_coefficients = zero_csp; wrk = zero_csp ! Orthogonalize vector y w.r.t. to Krylov basis X in two passes of GS. ! first pass call orthogonalize_against_basis(y, X, info, if_chk_orthonormal=.false., beta=proj_coefficients) call check_info(info, 'orthogonalize_against_basis_p1', this_module, this_procedure//', pass 1') ! second pass call orthogonalize_against_basis(y, X, info, if_chk_orthonormal=.false., beta=wrk) call check_info(info, 'orthogonalize_against_basis_p2', this_module, this_procedure//', pass 2') ! combine passes proj_coefficients = proj_coefficients + wrk if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure DGS_basis_against_basis_csp character(len=*), parameter :: this_procedure = 'DGS_basis_against_basis_csp' logical :: chk_X_orthonormality complex(sp), dimension(size(X),size(Y)) :: proj_coefficients, wrk ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! if (time_lightkrylov()) call timer%start(this_procedure) info = 0 proj_coefficients = zero_csp; wrk = zero_csp ! Orthogonalize Krylov basis Y w.r.t. to Krylov basis X in two passes of GS. ! first pass call orthogonalize_against_basis(Y, X, info, if_chk_orthonormal=.false., beta=proj_coefficients) call check_info(info, 'orthogonalize_against_basis_p1', this_module, this_procedure//', first pass') ! second pass call orthogonalize_against_basis(Y, X, info, if_chk_orthonormal=.false., beta=wrk) call check_info(info, 'orthogonalize_against_basis_p2', this_module, this_procedure//', second pass') ! combine passes proj_coefficients = proj_coefficients + wrk if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure DGS_vector_against_basis_cdp character(len=*), parameter :: this_procedure = 'DGS_vector_against_basis_cdp' logical :: chk_X_orthonormality complex(dp), dimension(size(X)) :: proj_coefficients, wrk ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! if (time_lightkrylov()) call timer%start(this_procedure) info = 0 proj_coefficients = zero_cdp; wrk = zero_cdp ! Orthogonalize vector y w.r.t. to Krylov basis X in two passes of GS. ! first pass call orthogonalize_against_basis(y, X, info, if_chk_orthonormal=.false., beta=proj_coefficients) call check_info(info, 'orthogonalize_against_basis_p1', this_module, this_procedure//', pass 1') ! second pass call orthogonalize_against_basis(y, X, info, if_chk_orthonormal=.false., beta=wrk) call check_info(info, 'orthogonalize_against_basis_p2', this_module, this_procedure//', pass 2') ! combine passes proj_coefficients = proj_coefficients + wrk if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure DGS_basis_against_basis_cdp character(len=*), parameter :: this_procedure = 'DGS_basis_against_basis_cdp' logical :: chk_X_orthonormality complex(dp), dimension(size(X),size(Y)) :: proj_coefficients, wrk ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! if (time_lightkrylov()) call timer%start(this_procedure) info = 0 proj_coefficients = zero_cdp; wrk = zero_cdp ! Orthogonalize Krylov basis Y w.r.t. to Krylov basis X in two passes of GS. ! first pass call orthogonalize_against_basis(Y, X, info, if_chk_orthonormal=.false., beta=proj_coefficients) call check_info(info, 'orthogonalize_against_basis_p1', this_module, this_procedure//', first pass') ! second pass call orthogonalize_against_basis(Y, X, info, if_chk_orthonormal=.false., beta=wrk) call check_info(info, 'orthogonalize_against_basis_p2', this_module, this_procedure//', second pass') ! combine passes proj_coefficients = proj_coefficients + wrk if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure !------------------------------------------------------------------------------- !----- ORTHOGONALIZE VECTOR/BASIS AGAINST ALREADY ORTHOGONAL BASIS ----- !------------------------------------------------------------------------------- module procedure orthogonalize_vector_against_basis_rsp character(len=*), parameter :: this_procedure = 'orthogonalize_vector_against_basis_rsp' logical :: chk_X_orthonormality real(sp) :: proj_coefficients(size(X)) if (time_lightkrylov()) call timer%start(this_procedure) info = 0 ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! ! check for zero vector if (y%norm() < atol_sp) info = 1 if (chk_X_orthonormality) then block real(sp), dimension(size(X), size(X)) :: G G = Gram(X) if (abs(G(size(X),size(X))) < rtol_sp) then ! The last vector in X is zero, it does not impact orthogonalisation info = -2 else if (mnorm(G - eye(size(X)), "Fro") > rtol_sp) then ! The basis is not orthonormal. Cannot orthonormalize. info = -1 return end if end block end if ! orthogonalize proj_coefficients = innerprod(X, y) block class(abstract_vector_rsp), allocatable :: proj call linear_combination(proj, X, proj_coefficients) call y%sub(proj) end block if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure orthogonalize_basis_against_basis_rsp character(len=*), parameter :: this_procedure = 'orthogonalize_basis_against_basis_rsp' logical :: chk_X_orthonormality real(sp) :: proj_coefficients(size(X), size(Y)) integer :: i if (time_lightkrylov()) call timer%start(this_procedure) info = 0 ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! ! check for zero vector do i = 1, size(Y) if (Y(i)%norm() < atol_sp) info = i end do if (chk_X_orthonormality) then block real(sp), dimension(size(X), size(X)) :: G G = Gram(X) if (abs(G(size(X),size(X))) < rtol_sp) then ! The last vector in X is zero, it does not impact orthogonalisation info = -2 else if (mnorm(G - eye(size(X)), "Fro") > rtol_sp) then ! The basis is not orthonormal. Cannot orthonormalize. info = -1 return end if end block end if ! orthogonalize proj_coefficients = innerprod(X, Y) block class(abstract_vector_rsp), allocatable :: proj(:) call linear_combination(proj, X, proj_coefficients) call axpby_basis(-one_rsp, proj, one_rsp, Y) end block if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure orthogonalize_vector_against_basis_rdp character(len=*), parameter :: this_procedure = 'orthogonalize_vector_against_basis_rdp' logical :: chk_X_orthonormality real(dp) :: proj_coefficients(size(X)) if (time_lightkrylov()) call timer%start(this_procedure) info = 0 ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! ! check for zero vector if (y%norm() < atol_dp) info = 1 if (chk_X_orthonormality) then block real(dp), dimension(size(X), size(X)) :: G G = Gram(X) if (abs(G(size(X),size(X))) < rtol_dp) then ! The last vector in X is zero, it does not impact orthogonalisation info = -2 else if (mnorm(G - eye(size(X)), "Fro") > rtol_dp) then ! The basis is not orthonormal. Cannot orthonormalize. info = -1 return end if end block end if ! orthogonalize proj_coefficients = innerprod(X, y) block class(abstract_vector_rdp), allocatable :: proj call linear_combination(proj, X, proj_coefficients) call y%sub(proj) end block if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure orthogonalize_basis_against_basis_rdp character(len=*), parameter :: this_procedure = 'orthogonalize_basis_against_basis_rdp' logical :: chk_X_orthonormality real(dp) :: proj_coefficients(size(X), size(Y)) integer :: i if (time_lightkrylov()) call timer%start(this_procedure) info = 0 ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! ! check for zero vector do i = 1, size(Y) if (Y(i)%norm() < atol_dp) info = i end do if (chk_X_orthonormality) then block real(dp), dimension(size(X), size(X)) :: G G = Gram(X) if (abs(G(size(X),size(X))) < rtol_dp) then ! The last vector in X is zero, it does not impact orthogonalisation info = -2 else if (mnorm(G - eye(size(X)), "Fro") > rtol_dp) then ! The basis is not orthonormal. Cannot orthonormalize. info = -1 return end if end block end if ! orthogonalize proj_coefficients = innerprod(X, Y) block class(abstract_vector_rdp), allocatable :: proj(:) call linear_combination(proj, X, proj_coefficients) call axpby_basis(-one_rdp, proj, one_rdp, Y) end block if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure orthogonalize_vector_against_basis_csp character(len=*), parameter :: this_procedure = 'orthogonalize_vector_against_basis_csp' logical :: chk_X_orthonormality complex(sp) :: proj_coefficients(size(X)) if (time_lightkrylov()) call timer%start(this_procedure) info = 0 ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! ! check for zero vector if (y%norm() < atol_sp) info = 1 if (chk_X_orthonormality) then block complex(sp), dimension(size(X), size(X)) :: G G = Gram(X) if (abs(G(size(X),size(X))) < rtol_sp) then ! The last vector in X is zero, it does not impact orthogonalisation info = -2 else if (mnorm(G - eye(size(X)), "Fro") > rtol_sp) then ! The basis is not orthonormal. Cannot orthonormalize. info = -1 return end if end block end if ! orthogonalize proj_coefficients = innerprod(X, y) block class(abstract_vector_csp), allocatable :: proj call linear_combination(proj, X, proj_coefficients) call y%sub(proj) end block if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure orthogonalize_basis_against_basis_csp character(len=*), parameter :: this_procedure = 'orthogonalize_basis_against_basis_csp' logical :: chk_X_orthonormality complex(sp) :: proj_coefficients(size(X), size(Y)) integer :: i if (time_lightkrylov()) call timer%start(this_procedure) info = 0 ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! ! check for zero vector do i = 1, size(Y) if (Y(i)%norm() < atol_sp) info = i end do if (chk_X_orthonormality) then block complex(sp), dimension(size(X), size(X)) :: G G = Gram(X) if (abs(G(size(X),size(X))) < rtol_sp) then ! The last vector in X is zero, it does not impact orthogonalisation info = -2 else if (mnorm(G - eye(size(X)), "Fro") > rtol_sp) then ! The basis is not orthonormal. Cannot orthonormalize. info = -1 return end if end block end if ! orthogonalize proj_coefficients = innerprod(X, Y) block class(abstract_vector_csp), allocatable :: proj(:) call linear_combination(proj, X, proj_coefficients) call axpby_basis(-one_csp, proj, one_csp, Y) end block if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure orthogonalize_vector_against_basis_cdp character(len=*), parameter :: this_procedure = 'orthogonalize_vector_against_basis_cdp' logical :: chk_X_orthonormality complex(dp) :: proj_coefficients(size(X)) if (time_lightkrylov()) call timer%start(this_procedure) info = 0 ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! ! check for zero vector if (y%norm() < atol_dp) info = 1 if (chk_X_orthonormality) then block complex(dp), dimension(size(X), size(X)) :: G G = Gram(X) if (abs(G(size(X),size(X))) < rtol_dp) then ! The last vector in X is zero, it does not impact orthogonalisation info = -2 else if (mnorm(G - eye(size(X)), "Fro") > rtol_dp) then ! The basis is not orthonormal. Cannot orthonormalize. info = -1 return end if end block end if ! orthogonalize proj_coefficients = innerprod(X, y) block class(abstract_vector_cdp), allocatable :: proj call linear_combination(proj, X, proj_coefficients) call y%sub(proj) end block if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure module procedure orthogonalize_basis_against_basis_cdp character(len=*), parameter :: this_procedure = 'orthogonalize_basis_against_basis_cdp' logical :: chk_X_orthonormality complex(dp) :: proj_coefficients(size(X), size(Y)) integer :: i if (time_lightkrylov()) call timer%start(this_procedure) info = 0 ! optional input argument chk_X_orthonormality = optval(if_chk_orthonormal, .true.) ! default to true! ! check for zero vector do i = 1, size(Y) if (Y(i)%norm() < atol_dp) info = i end do if (chk_X_orthonormality) then block complex(dp), dimension(size(X), size(X)) :: G G = Gram(X) if (abs(G(size(X),size(X))) < rtol_dp) then ! The last vector in X is zero, it does not impact orthogonalisation info = -2 else if (mnorm(G - eye(size(X)), "Fro") > rtol_dp) then ! The basis is not orthonormal. Cannot orthonormalize. info = -1 return end if end block end if ! orthogonalize proj_coefficients = innerprod(X, Y) block class(abstract_vector_cdp), allocatable :: proj(:) call linear_combination(proj, X, proj_coefficients) call axpby_basis(-one_cdp, proj, one_cdp, Y) end block if (present(beta)) then ! check size call assert_shape(beta, shape(proj_coefficients), 'beta', this_module, this_procedure) beta = proj_coefficients end if if (time_lightkrylov()) call timer%stop(this_procedure) return end procedure end submodule