LAPACK  3.10.0
LAPACK: Linear Algebra PACKage
dlaqz2.f
Go to the documentation of this file.
1 *> \brief \b DLAQZ2
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
9 *> Download DLAQZ2 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqz2.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqz2.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqz2.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 * Definition:
19 * ===========
20 *
21 * SUBROUTINE DLAQZ2( ILQ, ILZ, K, ISTARTM, ISTOPM, IHI, A, LDA, B,
22 * $ LDB, NQ, QSTART, Q, LDQ, NZ, ZSTART, Z, LDZ )
23 * IMPLICIT NONE
24 *
25 * Arguments
26 * LOGICAL, INTENT( IN ) :: ILQ, ILZ
27 * INTEGER, INTENT( IN ) :: K, LDA, LDB, LDQ, LDZ, ISTARTM, ISTOPM,
28 * $ NQ, NZ, QSTART, ZSTART, IHI
29 * DOUBLE PRECISION :: A( LDA, * ), B( LDB, * ), Q( LDQ, * ), Z( LDZ,
30 * $ * )
31 * ..
32 *
33 *
34 *> \par Purpose:
35 * =============
36 *>
37 *> \verbatim
38 *>
39 *> DLAQZ2 chases a 2x2 shift bulge in a matrix pencil down a single position
40 *> \endverbatim
41 *
42 *
43 * Arguments:
44 * ==========
45 *
46 *>
47 *> \param[in] ILQ
48 *> \verbatim
49 *> ILQ is LOGICAL
50 *> Determines whether or not to update the matrix Q
51 *> \endverbatim
52 *>
53 *> \param[in] ILZ
54 *> \verbatim
55 *> ILZ is LOGICAL
56 *> Determines whether or not to update the matrix Z
57 *> \endverbatim
58 *>
59 *> \param[in] K
60 *> \verbatim
61 *> K is INTEGER
62 *> Index indicating the position of the bulge.
63 *> On entry, the bulge is located in
64 *> (A(k+1:k+2,k:k+1),B(k+1:k+2,k:k+1)).
65 *> On exit, the bulge is located in
66 *> (A(k+2:k+3,k+1:k+2),B(k+2:k+3,k+1:k+2)).
67 *> \endverbatim
68 *>
69 *> \param[in] ISTARTM
70 *> \verbatim
71 *> ISTARTM is INTEGER
72 *> \endverbatim
73 *>
74 *> \param[in] ISTOPM
75 *> \verbatim
76 *> ISTOPM is INTEGER
77 *> Updates to (A,B) are restricted to
78 *> (istartm:k+3,k:istopm). It is assumed
79 *> without checking that istartm <= k+1 and
80 *> k+2 <= istopm
81 *> \endverbatim
82 *>
83 *> \param[in] IHI
84 *> \verbatim
85 *> IHI is INTEGER
86 *> \endverbatim
87 *>
88 *> \param[inout] A
89 *> \verbatim
90 *> A is DOUBLE PRECISION array, dimension (LDA,N)
91 *> \endverbatim
92 *>
93 *> \param[in] LDA
94 *> \verbatim
95 *> LDA is INTEGER
96 *> The leading dimension of A as declared in
97 *> the calling procedure.
98 *> \endverbatim
99 *
100 *> \param[inout] B
101 *> \verbatim
102 *> B is DOUBLE PRECISION array, dimension (LDB,N)
103 *> \endverbatim
104 *>
105 *> \param[in] LDB
106 *> \verbatim
107 *> LDB is INTEGER
108 *> The leading dimension of B as declared in
109 *> the calling procedure.
110 *> \endverbatim
111 *>
112 *> \param[in] NQ
113 *> \verbatim
114 *> NQ is INTEGER
115 *> The order of the matrix Q
116 *> \endverbatim
117 *>
118 *> \param[in] QSTART
119 *> \verbatim
120 *> QSTART is INTEGER
121 *> Start index of the matrix Q. Rotations are applied
122 *> To columns k+2-qStart:k+4-qStart of Q.
123 *> \endverbatim
124 *
125 *> \param[inout] Q
126 *> \verbatim
127 *> Q is DOUBLE PRECISION array, dimension (LDQ,NQ)
128 *> \endverbatim
129 *>
130 *> \param[in] LDQ
131 *> \verbatim
132 *> LDQ is INTEGER
133 *> The leading dimension of Q as declared in
134 *> the calling procedure.
135 *> \endverbatim
136 *>
137 *> \param[in] NZ
138 *> \verbatim
139 *> NZ is INTEGER
140 *> The order of the matrix Z
141 *> \endverbatim
142 *>
143 *> \param[in] ZSTART
144 *> \verbatim
145 *> ZSTART is INTEGER
146 *> Start index of the matrix Z. Rotations are applied
147 *> To columns k+1-qStart:k+3-qStart of Z.
148 *> \endverbatim
149 *
150 *> \param[inout] Z
151 *> \verbatim
152 *> Z is DOUBLE PRECISION array, dimension (LDZ,NZ)
153 *> \endverbatim
154 *>
155 *> \param[in] LDZ
156 *> \verbatim
157 *> LDZ is INTEGER
158 *> The leading dimension of Q as declared in
159 *> the calling procedure.
160 *> \endverbatim
161 *
162 * Authors:
163 * ========
164 *
165 *> \author Thijs Steel, KU Leuven
166 *
167 *> \date May 2020
168 *
169 *> \ingroup doubleGEcomputational
170 *>
171 * =====================================================================
172  SUBROUTINE dlaqz2( ILQ, ILZ, K, ISTARTM, ISTOPM, IHI, A, LDA, B,
173  $ LDB, NQ, QSTART, Q, LDQ, NZ, ZSTART, Z, LDZ )
174  IMPLICIT NONE
175 *
176 * Arguments
177  LOGICAL, INTENT( IN ) :: ILQ, ILZ
178  INTEGER, INTENT( IN ) :: K, LDA, LDB, LDQ, LDZ, ISTARTM, ISTOPM,
179  $ nq, nz, qstart, zstart, ihi
180  DOUBLE PRECISION :: A( LDA, * ), B( LDB, * ), Q( LDQ, * ), Z( LDZ,
181  $ * )
182 *
183 * Parameters
184  DOUBLE PRECISION :: ZERO, ONE, HALF
185  parameter( zero = 0.0d0, one = 1.0d0, half = 0.5d0 )
186 *
187 * Local variables
188  DOUBLE PRECISION :: H( 2, 3 ), C1, S1, C2, S2, TEMP
189 *
190 * External functions
191  EXTERNAL :: dlartg, drot
192 *
193  IF( k+2 .EQ. ihi ) THEN
194 * Shift is located on the edge of the matrix, remove it
195  h = b( ihi-1:ihi, ihi-2:ihi )
196 * Make H upper triangular
197  CALL dlartg( h( 1, 1 ), h( 2, 1 ), c1, s1, temp )
198  h( 2, 1 ) = zero
199  h( 1, 1 ) = temp
200  CALL drot( 2, h( 1, 2 ), 2, h( 2, 2 ), 2, c1, s1 )
201 *
202  CALL dlartg( h( 2, 3 ), h( 2, 2 ), c1, s1, temp )
203  CALL drot( 1, h( 1, 3 ), 1, h( 1, 2 ), 1, c1, s1 )
204  CALL dlartg( h( 1, 2 ), h( 1, 1 ), c2, s2, temp )
205 *
206  CALL drot( ihi-istartm+1, b( istartm, ihi ), 1, b( istartm,
207  $ ihi-1 ), 1, c1, s1 )
208  CALL drot( ihi-istartm+1, b( istartm, ihi-1 ), 1, b( istartm,
209  $ ihi-2 ), 1, c2, s2 )
210  b( ihi-1, ihi-2 ) = zero
211  b( ihi, ihi-2 ) = zero
212  CALL drot( ihi-istartm+1, a( istartm, ihi ), 1, a( istartm,
213  $ ihi-1 ), 1, c1, s1 )
214  CALL drot( ihi-istartm+1, a( istartm, ihi-1 ), 1, a( istartm,
215  $ ihi-2 ), 1, c2, s2 )
216  IF ( ilz ) THEN
217  CALL drot( nz, z( 1, ihi-zstart+1 ), 1, z( 1, ihi-1-zstart+
218  $ 1 ), 1, c1, s1 )
219  CALL drot( nz, z( 1, ihi-1-zstart+1 ), 1, z( 1,
220  $ ihi-2-zstart+1 ), 1, c2, s2 )
221  END IF
222 *
223  CALL dlartg( a( ihi-1, ihi-2 ), a( ihi, ihi-2 ), c1, s1,
224  $ temp )
225  a( ihi-1, ihi-2 ) = temp
226  a( ihi, ihi-2 ) = zero
227  CALL drot( istopm-ihi+2, a( ihi-1, ihi-1 ), lda, a( ihi,
228  $ ihi-1 ), lda, c1, s1 )
229  CALL drot( istopm-ihi+2, b( ihi-1, ihi-1 ), ldb, b( ihi,
230  $ ihi-1 ), ldb, c1, s1 )
231  IF ( ilq ) THEN
232  CALL drot( nq, q( 1, ihi-1-qstart+1 ), 1, q( 1, ihi-qstart+
233  $ 1 ), 1, c1, s1 )
234  END IF
235 *
236  CALL dlartg( b( ihi, ihi ), b( ihi, ihi-1 ), c1, s1, temp )
237  b( ihi, ihi ) = temp
238  b( ihi, ihi-1 ) = zero
239  CALL drot( ihi-istartm, b( istartm, ihi ), 1, b( istartm,
240  $ ihi-1 ), 1, c1, s1 )
241  CALL drot( ihi-istartm+1, a( istartm, ihi ), 1, a( istartm,
242  $ ihi-1 ), 1, c1, s1 )
243  IF ( ilz ) THEN
244  CALL drot( nz, z( 1, ihi-zstart+1 ), 1, z( 1, ihi-1-zstart+
245  $ 1 ), 1, c1, s1 )
246  END IF
247 *
248  ELSE
249 *
250 * Normal operation, move bulge down
251 *
252  h = b( k+1:k+2, k:k+2 )
253 *
254 * Make H upper triangular
255 *
256  CALL dlartg( h( 1, 1 ), h( 2, 1 ), c1, s1, temp )
257  h( 2, 1 ) = zero
258  h( 1, 1 ) = temp
259  CALL drot( 2, h( 1, 2 ), 2, h( 2, 2 ), 2, c1, s1 )
260 *
261 * Calculate Z1 and Z2
262 *
263  CALL dlartg( h( 2, 3 ), h( 2, 2 ), c1, s1, temp )
264  CALL drot( 1, h( 1, 3 ), 1, h( 1, 2 ), 1, c1, s1 )
265  CALL dlartg( h( 1, 2 ), h( 1, 1 ), c2, s2, temp )
266 *
267 * Apply transformations from the right
268 *
269  CALL drot( k+3-istartm+1, a( istartm, k+2 ), 1, a( istartm,
270  $ k+1 ), 1, c1, s1 )
271  CALL drot( k+3-istartm+1, a( istartm, k+1 ), 1, a( istartm,
272  $ k ), 1, c2, s2 )
273  CALL drot( k+2-istartm+1, b( istartm, k+2 ), 1, b( istartm,
274  $ k+1 ), 1, c1, s1 )
275  CALL drot( k+2-istartm+1, b( istartm, k+1 ), 1, b( istartm,
276  $ k ), 1, c2, s2 )
277  IF ( ilz ) THEN
278  CALL drot( nz, z( 1, k+2-zstart+1 ), 1, z( 1, k+1-zstart+
279  $ 1 ), 1, c1, s1 )
280  CALL drot( nz, z( 1, k+1-zstart+1 ), 1, z( 1, k-zstart+1 ),
281  $ 1, c2, s2 )
282  END IF
283  b( k+1, k ) = zero
284  b( k+2, k ) = zero
285 *
286 * Calculate Q1 and Q2
287 *
288  CALL dlartg( a( k+2, k ), a( k+3, k ), c1, s1, temp )
289  a( k+2, k ) = temp
290  a( k+3, k ) = zero
291  CALL dlartg( a( k+1, k ), a( k+2, k ), c2, s2, temp )
292  a( k+1, k ) = temp
293  a( k+2, k ) = zero
294 *
295 * Apply transformations from the left
296 *
297  CALL drot( istopm-k, a( k+2, k+1 ), lda, a( k+3, k+1 ), lda,
298  $ c1, s1 )
299  CALL drot( istopm-k, a( k+1, k+1 ), lda, a( k+2, k+1 ), lda,
300  $ c2, s2 )
301 *
302  CALL drot( istopm-k, b( k+2, k+1 ), ldb, b( k+3, k+1 ), ldb,
303  $ c1, s1 )
304  CALL drot( istopm-k, b( k+1, k+1 ), ldb, b( k+2, k+1 ), ldb,
305  $ c2, s2 )
306  IF ( ilq ) THEN
307  CALL drot( nq, q( 1, k+2-qstart+1 ), 1, q( 1, k+3-qstart+
308  $ 1 ), 1, c1, s1 )
309  CALL drot( nq, q( 1, k+1-qstart+1 ), 1, q( 1, k+2-qstart+
310  $ 1 ), 1, c2, s2 )
311  END IF
312 *
313  END IF
314 *
315 * End of DLAQZ2
316 *
317  END SUBROUTINE
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
Definition: dlartg.f90:113
subroutine drot(N, DX, INCX, DY, INCY, C, S)
DROT
Definition: drot.f:92
subroutine dlaqz2(ILQ, ILZ, K, ISTARTM, ISTOPM, IHI, A, LDA, B, LDB, NQ, QSTART, Q, LDQ, NZ, ZSTART, Z, LDZ)
DLAQZ2
Definition: dlaqz2.f:174