LAPACK 3.12.0
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
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 laqz2
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 dlaqz2(ilq, ilz, k, istartm, istopm, ihi, a, lda, b, ldb, nq, qstart, q, ldq, nz, zstart, z, ldz)
DLAQZ2
Definition dlaqz2.f:174
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
Definition dlartg.f90:111
subroutine drot(n, dx, incx, dy, incy, c, s)
DROT
Definition drot.f:92