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