ROMS
Loading...
Searching...
No Matches
sqlq.F
Go to the documentation of this file.
1#include "cppdefs.h"
2
3#if defined WEAK_CONSTRAINT && defined MINRES
4 SUBROUTINE sqlq (innLoop, a, tau, y)
5!
6!git $Id$
7!================================================== Hernan G. Arango ===
8! Copyright (c) 2002-2025 The ROMS Group Andrew M. Moore !
9! Licensed under a MIT/X style license !
10! See License_ROMS.md !
11!=======================================================================
12! !
13! This routine performs an LQ factorization of the square matrix A. !
14! The algorithm is based on that used in the LAPACK routine DGELQF. !
15! !
16! NOTE: A, TAU and Y are overwritten on exit. !
17! !
18! On exit, the elements on and below the diagonal of the array !
19! contain the innLoop-by-innLoop lower trapezoidal matrix L (L is !
20! lower triangular; the elements above the diagonal, !
21! with the array TAU, represent the orthogonal matrix Q as a !
22! product of elementary reflectors. !
23! The matrix Q is represented as a product of elementary reflectors !
24! !
25! Q = H(innLoop) . . . H(2) H(1) !
26! !
27! Each H(i) has the form !
28! !
29! H(i) = I - tau * v * v' !
30! !
31! where tau is a real scalar, and v is a real vector with !
32! v(1:i-1) = 0 and v(i) = 1; v(i+1:innLoop) is stored on exit in !
33! A(i,i+1:innLoop), and tau in TAU(i). !
34! !
35!=======================================================================
36!
37 USE mod_kinds
38!
39 implicit none
40!
41! Imported variable declarations
42!
43 integer, intent(in) :: innLoop
44
45 real(r8), dimension(innLoop,innLoop), intent(inout) :: a
46 real(r8), dimension(innLoop), intent(inout) :: tau, y
47!
48! Local variable declarations.
49!
50 integer :: i, j, ii, jj
51
52 real(r8) :: znorm, zbeta, zaii, ztemp
53!
54!-----------------------------------------------------------------------
55! LQ factorization of a square matrix.
56!-----------------------------------------------------------------------
57!
58 DO i=1,innloop
59 tau(i)=0.0_r8
60 END DO
61!
62 DO ii=1,innloop-1
63!
64! Generate elementary reflector H(ii) to annihilate A(ii,ii+1:innLoop).
65!
66 znorm=0.0_r8
67 DO j=ii+1,innloop
68 znorm=znorm+a(ii,j)*a(ii,j)
69 END DO
70 znorm=sqrt(znorm)
71 zbeta=sqrt(znorm*znorm+a(ii,ii)*a(ii,ii))
72 zbeta=-sign(zbeta,a(ii,ii))
73 tau(ii)=(zbeta-a(ii,ii))/zbeta
74 DO j=ii+1,innloop
75 a(ii,j)=a(ii,j)/(a(ii,ii)-zbeta)
76 END DO
77 a(ii,ii)=zbeta
78!
79! Apply H(ii) to A(ii+1:innLoop,ii:innLoop) from the right.
80!
81 zaii=a(ii,ii)
82 a(ii,ii)=1.0_r8
83 IF (tau(ii).ne.0.0_r8) THEN
84 DO i=1,innloop
85 y(i)=0.0_r8
86 END DO
87 jj=ii-1
88 DO j=1,innloop-jj
89 ztemp=a(ii,j+jj)
90 DO i=1,innloop-ii
91 y(i)=y(i)+ztemp*a(ii+i,j+jj)
92 END DO
93 END DO
94!
95 DO j=1,innloop-jj
96 ztemp=-tau(ii)*a(ii,j+jj)
97 DO i=1,innloop-ii
98 a(ii+i,j+jj)=a(ii+i,j+jj)+y(i)*ztemp
99 END DO
100 END DO
101 END IF
102 a(ii,ii)=zaii
103 END DO
104!
105 RETURN
106 END SUBROUTINE sqlq
107#else
108 SUBROUTINE sqlq
109 RETURN
110 END SUBROUTINE sqlq
111#endif
112
113