LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
stgexc.f
Go to the documentation of this file.
1*> \brief \b STGEXC
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download STGEXC + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/stgexc.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/stgexc.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/stgexc.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE STGEXC( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
20* LDZ, IFST, ILST, WORK, LWORK, INFO )
21*
22* .. Scalar Arguments ..
23* LOGICAL WANTQ, WANTZ
24* INTEGER IFST, ILST, INFO, LDA, LDB, LDQ, LDZ, LWORK, N
25* ..
26* .. Array Arguments ..
27* REAL A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
28* $ WORK( * ), Z( LDZ, * )
29* ..
30*
31*
32*> \par Purpose:
33* =============
34*>
35*> \verbatim
36*>
37*> STGEXC reorders the generalized real Schur decomposition of a real
38*> matrix pair (A,B) using an orthogonal equivalence transformation
39*>
40*> (A, B) = Q * (A, B) * Z**T,
41*>
42*> so that the diagonal block of (A, B) with row index IFST is moved
43*> to row ILST.
44*>
45*> (A, B) must be in generalized real Schur canonical form (as returned
46*> by SGGES), i.e. A is block upper triangular with 1-by-1 and 2-by-2
47*> diagonal blocks. B is upper triangular.
48*>
49*> Optionally, the matrices Q and Z of generalized Schur vectors are
50*> updated.
51*>
52*> Q(in) * A(in) * Z(in)**T = Q(out) * A(out) * Z(out)**T
53*> Q(in) * B(in) * Z(in)**T = Q(out) * B(out) * Z(out)**T
54*>
55*> \endverbatim
56*
57* Arguments:
58* ==========
59*
60*> \param[in] WANTQ
61*> \verbatim
62*> WANTQ is LOGICAL
63*> .TRUE. : update the left transformation matrix Q;
64*> .FALSE.: do not update Q.
65*> \endverbatim
66*>
67*> \param[in] WANTZ
68*> \verbatim
69*> WANTZ is LOGICAL
70*> .TRUE. : update the right transformation matrix Z;
71*> .FALSE.: do not update Z.
72*> \endverbatim
73*>
74*> \param[in] N
75*> \verbatim
76*> N is INTEGER
77*> The order of the matrices A and B. N >= 0.
78*> \endverbatim
79*>
80*> \param[in,out] A
81*> \verbatim
82*> A is REAL array, dimension (LDA,N)
83*> On entry, the matrix A in generalized real Schur canonical
84*> form.
85*> On exit, the updated matrix A, again in generalized
86*> real Schur canonical form.
87*> \endverbatim
88*>
89*> \param[in] LDA
90*> \verbatim
91*> LDA is INTEGER
92*> The leading dimension of the array A. LDA >= max(1,N).
93*> \endverbatim
94*>
95*> \param[in,out] B
96*> \verbatim
97*> B is REAL array, dimension (LDB,N)
98*> On entry, the matrix B in generalized real Schur canonical
99*> form (A,B).
100*> On exit, the updated matrix B, again in generalized
101*> real Schur canonical form (A,B).
102*> \endverbatim
103*>
104*> \param[in] LDB
105*> \verbatim
106*> LDB is INTEGER
107*> The leading dimension of the array B. LDB >= max(1,N).
108*> \endverbatim
109*>
110*> \param[in,out] Q
111*> \verbatim
112*> Q is REAL array, dimension (LDQ,N)
113*> On entry, if WANTQ = .TRUE., the orthogonal matrix Q.
114*> On exit, the updated matrix Q.
115*> If WANTQ = .FALSE., Q is not referenced.
116*> \endverbatim
117*>
118*> \param[in] LDQ
119*> \verbatim
120*> LDQ is INTEGER
121*> The leading dimension of the array Q. LDQ >= 1.
122*> If WANTQ = .TRUE., LDQ >= N.
123*> \endverbatim
124*>
125*> \param[in,out] Z
126*> \verbatim
127*> Z is REAL array, dimension (LDZ,N)
128*> On entry, if WANTZ = .TRUE., the orthogonal matrix Z.
129*> On exit, the updated matrix Z.
130*> If WANTZ = .FALSE., Z is not referenced.
131*> \endverbatim
132*>
133*> \param[in] LDZ
134*> \verbatim
135*> LDZ is INTEGER
136*> The leading dimension of the array Z. LDZ >= 1.
137*> If WANTZ = .TRUE., LDZ >= N.
138*> \endverbatim
139*>
140*> \param[in,out] IFST
141*> \verbatim
142*> IFST is INTEGER
143*> \endverbatim
144*>
145*> \param[in,out] ILST
146*> \verbatim
147*> ILST is INTEGER
148*> Specify the reordering of the diagonal blocks of (A, B).
149*> The block with row index IFST is moved to row ILST, by a
150*> sequence of swapping between adjacent blocks.
151*> On exit, if IFST pointed on entry to the second row of
152*> a 2-by-2 block, it is changed to point to the first row;
153*> ILST always points to the first row of the block in its
154*> final position (which may differ from its input value by
155*> +1 or -1). 1 <= IFST, ILST <= N.
156*> \endverbatim
157*>
158*> \param[out] WORK
159*> \verbatim
160*> WORK is REAL array, dimension (MAX(1,LWORK))
161*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
162*> \endverbatim
163*>
164*> \param[in] LWORK
165*> \verbatim
166*> LWORK is INTEGER
167*> The dimension of the array WORK.
168*> LWORK >= 1 when N <= 1, otherwise LWORK >= 4*N + 16.
169*>
170*> If LWORK = -1, then a workspace query is assumed; the routine
171*> only calculates the optimal size of the WORK array, returns
172*> this value as the first entry of the WORK array, and no error
173*> message related to LWORK is issued by XERBLA.
174*> \endverbatim
175*>
176*> \param[out] INFO
177*> \verbatim
178*> INFO is INTEGER
179*> =0: successful exit.
180*> <0: if INFO = -i, the i-th argument had an illegal value.
181*> =1: The transformed matrix pair (A, B) would be too far
182*> from generalized Schur form; the problem is ill-
183*> conditioned. (A, B) may have been partially reordered,
184*> and ILST points to the first row of the current
185*> position of the block being moved.
186*> \endverbatim
187*
188* Authors:
189* ========
190*
191*> \author Univ. of Tennessee
192*> \author Univ. of California Berkeley
193*> \author Univ. of Colorado Denver
194*> \author NAG Ltd.
195*
196*> \ingroup tgexc
197*
198*> \par Contributors:
199* ==================
200*>
201*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,
202*> Umea University, S-901 87 Umea, Sweden.
203*
204*> \par References:
205* ================
206*>
207*> \verbatim
208*>
209*> [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the
210*> Generalized Real Schur Form of a Regular Matrix Pair (A, B), in
211*> M.S. Moonen et al (eds), Linear Algebra for Large Scale and
212*> Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.
213*> \endverbatim
214*>
215* =====================================================================
216 SUBROUTINE stgexc( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
217 $ LDZ, IFST, ILST, WORK, LWORK, INFO )
218*
219* -- LAPACK computational routine --
220* -- LAPACK is a software package provided by Univ. of Tennessee, --
221* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
222*
223* .. Scalar Arguments ..
224 LOGICAL WANTQ, WANTZ
225 INTEGER IFST, ILST, INFO, LDA, LDB, LDQ, LDZ, LWORK, N
226* ..
227* .. Array Arguments ..
228 REAL A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
229 $ work( * ), z( ldz, * )
230* ..
231*
232* =====================================================================
233*
234* .. Parameters ..
235 REAL ZERO
236 parameter( zero = 0.0e+0 )
237* ..
238* .. Local Scalars ..
239 LOGICAL LQUERY
240 INTEGER HERE, LWMIN, NBF, NBL, NBNEXT
241* ..
242* .. External Functions ..
243 REAL SROUNDUP_LWORK
244 EXTERNAL sroundup_lwork
245* ..
246* .. External Subroutines ..
247 EXTERNAL stgex2, xerbla
248* ..
249* .. Intrinsic Functions ..
250 INTRINSIC max
251* ..
252* .. Executable Statements ..
253*
254* Decode and test input arguments.
255*
256 info = 0
257 lquery = ( lwork.EQ.-1 )
258 IF( n.LT.0 ) THEN
259 info = -3
260 ELSE IF( lda.LT.max( 1, n ) ) THEN
261 info = -5
262 ELSE IF( ldb.LT.max( 1, n ) ) THEN
263 info = -7
264 ELSE IF( ldq.LT.1 .OR. wantq .AND. ( ldq.LT.max( 1, n ) ) ) THEN
265 info = -9
266 ELSE IF( ldz.LT.1 .OR. wantz .AND. ( ldz.LT.max( 1, n ) ) ) THEN
267 info = -11
268 ELSE IF( ifst.LT.1 .OR. ifst.GT.n ) THEN
269 info = -12
270 ELSE IF( ilst.LT.1 .OR. ilst.GT.n ) THEN
271 info = -13
272 END IF
273*
274 IF( info.EQ.0 ) THEN
275 IF( n.LE.1 ) THEN
276 lwmin = 1
277 ELSE
278 lwmin = 4*n + 16
279 END IF
280 work(1) = real( lwmin )
281*
282 IF (lwork.LT.lwmin .AND. .NOT.lquery) THEN
283 info = -15
284 END IF
285 END IF
286*
287 IF( info.NE.0 ) THEN
288 CALL xerbla( 'STGEXC', -info )
289 RETURN
290 ELSE IF( lquery ) THEN
291 RETURN
292 END IF
293*
294* Quick return if possible
295*
296 IF( n.LE.1 )
297 $ RETURN
298*
299* Determine the first row of the specified block and find out
300* if it is 1-by-1 or 2-by-2.
301*
302 IF( ifst.GT.1 ) THEN
303 IF( a( ifst, ifst-1 ).NE.zero )
304 $ ifst = ifst - 1
305 END IF
306 nbf = 1
307 IF( ifst.LT.n ) THEN
308 IF( a( ifst+1, ifst ).NE.zero )
309 $ nbf = 2
310 END IF
311*
312* Determine the first row of the final block
313* and find out if it is 1-by-1 or 2-by-2.
314*
315 IF( ilst.GT.1 ) THEN
316 IF( a( ilst, ilst-1 ).NE.zero )
317 $ ilst = ilst - 1
318 END IF
319 nbl = 1
320 IF( ilst.LT.n ) THEN
321 IF( a( ilst+1, ilst ).NE.zero )
322 $ nbl = 2
323 END IF
324 IF( ifst.EQ.ilst )
325 $ RETURN
326*
327 IF( ifst.LT.ilst ) THEN
328*
329* Update ILST.
330*
331 IF( nbf.EQ.2 .AND. nbl.EQ.1 )
332 $ ilst = ilst - 1
333 IF( nbf.EQ.1 .AND. nbl.EQ.2 )
334 $ ilst = ilst + 1
335*
336 here = ifst
337*
338 10 CONTINUE
339*
340* Swap with next one below.
341*
342 IF( nbf.EQ.1 .OR. nbf.EQ.2 ) THEN
343*
344* Current block either 1-by-1 or 2-by-2.
345*
346 nbnext = 1
347 IF( here+nbf+1.LE.n ) THEN
348 IF( a( here+nbf+1, here+nbf ).NE.zero )
349 $ nbnext = 2
350 END IF
351 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q, ldq, z,
352 $ ldz, here, nbf, nbnext, work, lwork, info )
353 IF( info.NE.0 ) THEN
354 ilst = here
355 RETURN
356 END IF
357 here = here + nbnext
358*
359* Test if 2-by-2 block breaks into two 1-by-1 blocks.
360*
361 IF( nbf.EQ.2 ) THEN
362 IF( a( here+1, here ).EQ.zero )
363 $ nbf = 3
364 END IF
365*
366 ELSE
367*
368* Current block consists of two 1-by-1 blocks, each of which
369* must be swapped individually.
370*
371 nbnext = 1
372 IF( here+3.LE.n ) THEN
373 IF( a( here+3, here+2 ).NE.zero )
374 $ nbnext = 2
375 END IF
376 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q, ldq, z,
377 $ ldz, here+1, 1, nbnext, work, lwork, info )
378 IF( info.NE.0 ) THEN
379 ilst = here
380 RETURN
381 END IF
382 IF( nbnext.EQ.1 ) THEN
383*
384* Swap two 1-by-1 blocks.
385*
386 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q, ldq,
387 $ z,
388 $ ldz, here, 1, 1, work, lwork, info )
389 IF( info.NE.0 ) THEN
390 ilst = here
391 RETURN
392 END IF
393 here = here + 1
394*
395 ELSE
396*
397* Recompute NBNEXT in case of 2-by-2 split.
398*
399 IF( a( here+2, here+1 ).EQ.zero )
400 $ nbnext = 1
401 IF( nbnext.EQ.2 ) THEN
402*
403* 2-by-2 block did not split.
404*
405 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q,
406 $ ldq,
407 $ z, ldz, here, 1, nbnext, work, lwork,
408 $ info )
409 IF( info.NE.0 ) THEN
410 ilst = here
411 RETURN
412 END IF
413 here = here + 2
414 ELSE
415*
416* 2-by-2 block did split.
417*
418 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q,
419 $ ldq,
420 $ z, ldz, here, 1, 1, work, lwork, info )
421 IF( info.NE.0 ) THEN
422 ilst = here
423 RETURN
424 END IF
425 here = here + 1
426 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q,
427 $ ldq,
428 $ z, ldz, here, 1, 1, work, lwork, info )
429 IF( info.NE.0 ) THEN
430 ilst = here
431 RETURN
432 END IF
433 here = here + 1
434 END IF
435*
436 END IF
437 END IF
438 IF( here.LT.ilst )
439 $ GO TO 10
440 ELSE
441 here = ifst
442*
443 20 CONTINUE
444*
445* Swap with next one below.
446*
447 IF( nbf.EQ.1 .OR. nbf.EQ.2 ) THEN
448*
449* Current block either 1-by-1 or 2-by-2.
450*
451 nbnext = 1
452 IF( here.GE.3 ) THEN
453 IF( a( here-1, here-2 ).NE.zero )
454 $ nbnext = 2
455 END IF
456 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q, ldq, z,
457 $ ldz, here-nbnext, nbnext, nbf, work, lwork,
458 $ info )
459 IF( info.NE.0 ) THEN
460 ilst = here
461 RETURN
462 END IF
463 here = here - nbnext
464*
465* Test if 2-by-2 block breaks into two 1-by-1 blocks.
466*
467 IF( nbf.EQ.2 ) THEN
468 IF( a( here+1, here ).EQ.zero )
469 $ nbf = 3
470 END IF
471*
472 ELSE
473*
474* Current block consists of two 1-by-1 blocks, each of which
475* must be swapped individually.
476*
477 nbnext = 1
478 IF( here.GE.3 ) THEN
479 IF( a( here-1, here-2 ).NE.zero )
480 $ nbnext = 2
481 END IF
482 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q, ldq, z,
483 $ ldz, here-nbnext, nbnext, 1, work, lwork,
484 $ info )
485 IF( info.NE.0 ) THEN
486 ilst = here
487 RETURN
488 END IF
489 IF( nbnext.EQ.1 ) THEN
490*
491* Swap two 1-by-1 blocks.
492*
493 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q, ldq,
494 $ z,
495 $ ldz, here, nbnext, 1, work, lwork, info )
496 IF( info.NE.0 ) THEN
497 ilst = here
498 RETURN
499 END IF
500 here = here - 1
501 ELSE
502*
503* Recompute NBNEXT in case of 2-by-2 split.
504*
505 IF( a( here, here-1 ).EQ.zero )
506 $ nbnext = 1
507 IF( nbnext.EQ.2 ) THEN
508*
509* 2-by-2 block did not split.
510*
511 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q,
512 $ ldq,
513 $ z, ldz, here-1, 2, 1, work, lwork, info )
514 IF( info.NE.0 ) THEN
515 ilst = here
516 RETURN
517 END IF
518 here = here - 2
519 ELSE
520*
521* 2-by-2 block did split.
522*
523 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q,
524 $ ldq,
525 $ z, ldz, here, 1, 1, work, lwork, info )
526 IF( info.NE.0 ) THEN
527 ilst = here
528 RETURN
529 END IF
530 here = here - 1
531 CALL stgex2( wantq, wantz, n, a, lda, b, ldb, q,
532 $ ldq,
533 $ z, ldz, here, 1, 1, work, lwork, info )
534 IF( info.NE.0 ) THEN
535 ilst = here
536 RETURN
537 END IF
538 here = here - 1
539 END IF
540 END IF
541 END IF
542 IF( here.GT.ilst )
543 $ GO TO 20
544 END IF
545 ilst = here
546 work( 1 ) = sroundup_lwork(lwmin)
547 RETURN
548*
549* End of STGEXC
550*
551 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine stgex2(wantq, wantz, n, a, lda, b, ldb, q, ldq, z, ldz, j1, n1, n2, work, lwork, info)
STGEX2 swaps adjacent diagonal blocks in an upper (quasi) triangular matrix pair by an orthogonal equ...
Definition stgex2.f:219
subroutine stgexc(wantq, wantz, n, a, lda, b, ldb, q, ldq, z, ldz, ifst, ilst, work, lwork, info)
STGEXC
Definition stgexc.f:218