208 SUBROUTINE slaqz4( ILSCHUR, ILQ, ILZ, N, ILO, IHI, NSHIFTS,
209 $ NBLOCK_DESIRED, SR, SI, SS, A, LDA, B, LDB, Q,
210 $ LDQ, Z, LDZ, QC, LDQC, ZC, LDZC, WORK, LWORK,
215 LOGICAL,
INTENT( IN ) :: ILSCHUR, ILQ, ILZ
216 INTEGER,
INTENT( IN ) :: N, ILO, IHI, LDA, LDB, LDQ, LDZ, LWORK,
217 $ NSHIFTS, NBLOCK_DESIRED, LDQC, LDZC
219 REAL,
INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
220 $ Z( LDZ, * ), QC( LDQC, * ), ZC( LDZC, * ), WORK( * ), SR( * ),
223 INTEGER,
INTENT( OUT ) :: INFO
226 REAL :: ZERO, ONE, HALF
227 PARAMETER( ZERO = 0.0, one = 1.0, half = 0.5 )
230 INTEGER :: I, J, NS, ISTARTM, ISTOPM, SHEIGHT, SWIDTH, K, NP,
231 $ ISTARTB, ISTOPB, ISHIFT, NBLOCK, NPOS
232 REAL :: TEMP, V( 3 ), C1, S1, C2, S2, SWAP
237 REAL,
EXTERNAL :: SROUNDUP_LWORK
240 IF ( nblock_desired .LT. nshifts+1 )
THEN
243 IF ( lwork .EQ.-1 )
THEN
245 work( 1 ) = sroundup_lwork(n*nblock_desired)
247 ELSE IF ( lwork .LT. n*nblock_desired )
THEN
252 CALL xerbla(
'SLAQZ4', -info )
258 IF ( nshifts .LT. 2 )
THEN
262 IF ( ilo .GE. ihi )
THEN
279 DO i = 1, nshifts-2, 2
280 IF( si( i ).NE.-si( i+1 ) )
THEN
284 sr( i+1 ) = sr( i+2 )
289 si( i+1 ) = si( i+2 )
294 ss( i+1 ) = ss( i+2 )
304 ns = nshifts-mod( nshifts, 2 )
305 npos = max( nblock_desired-ns, 1 )
312 CALL slaset(
'FULL', ns+1, ns+1, zero, one, qc, ldqc )
313 CALL slaset(
'FULL', ns, ns, zero, one, zc, ldzc )
317 CALL slaqz1( a( ilo, ilo ), lda, b( ilo, ilo ), ldb,
319 $ sr( i+1 ), si( i ), ss( i ), ss( i+1 ), v )
322 CALL slartg( temp, v( 3 ), c1, s1, v( 2 ) )
323 CALL slartg( v( 1 ), v( 2 ), c2, s2, temp )
325 CALL srot( ns, a( ilo+1, ilo ), lda, a( ilo+2, ilo ), lda,
328 CALL srot( ns, a( ilo, ilo ), lda, a( ilo+1, ilo ), lda, c2,
330 CALL srot( ns, b( ilo+1, ilo ), ldb, b( ilo+2, ilo ), ldb,
333 CALL srot( ns, b( ilo, ilo ), ldb, b( ilo+1, ilo ), ldb, c2,
335 CALL srot( ns+1, qc( 1, 2 ), 1, qc( 1, 3 ), 1, c1, s1 )
336 CALL srot( ns+1, qc( 1, 1 ), 1, qc( 1, 2 ), 1, c2, s2 )
341 CALL slaqz2( .true., .true., j, 1, ns, ihi-ilo+1, a( ilo,
342 $ ilo ), lda, b( ilo, ilo ), ldb, ns+1, 1, qc,
343 $ ldqc, ns, 1, zc, ldzc )
354 swidth = istopm-( ilo+ns )+1
355 IF ( swidth > 0 )
THEN
356 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc,
358 $ a( ilo, ilo+ns ), lda, zero, work, sheight )
359 CALL slacpy(
'ALL', sheight, swidth, work, sheight, a( ilo,
361 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc,
363 $ b( ilo, ilo+ns ), ldb, zero, work, sheight )
364 CALL slacpy(
'ALL', sheight, swidth, work, sheight, b( ilo,
368 CALL sgemm(
'N',
'N', n, sheight, sheight, one, q( 1, ilo ),
369 $ ldq, qc, ldqc, zero, work, n )
370 CALL slacpy(
'ALL', n, sheight, work, n, q( 1, ilo ), ldq )
375 sheight = ilo-1-istartm+1
377 IF ( sheight > 0 )
THEN
378 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one,
380 $ ilo ), lda, zc, ldzc, zero, work, sheight )
381 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
384 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one,
386 $ ilo ), ldb, zc, ldzc, zero, work, sheight )
387 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
392 CALL sgemm(
'N',
'N', n, swidth, swidth, one, z( 1, ilo ),
394 $ zc, ldzc, zero, work, n )
395 CALL slacpy(
'ALL', n, swidth, work, n, z( 1, ilo ), ldz )
403 DO WHILE ( k < ihi-ns )
404 np = min( ihi-ns-k, npos )
412 CALL slaset(
'FULL', ns+np, ns+np, zero, one, qc, ldqc )
413 CALL slaset(
'FULL', ns+np, ns+np, zero, one, zc, ldzc )
421 CALL slaqz2( .true., .true., k+i+j-1, istartb, istopb,
422 $ ihi, a, lda, b, ldb, nblock, k+1, qc, ldqc,
423 $ nblock, k, zc, ldzc )
433 swidth = istopm-( k+ns+np )+1
434 IF ( swidth > 0 )
THEN
435 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc,
436 $ ldqc, a( k+1, k+ns+np ), lda, zero, work,
438 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
441 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc,
442 $ ldqc, b( k+1, k+ns+np ), ldb, zero, work,
444 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
449 CALL sgemm(
'N',
'N', n, nblock, nblock, one, q( 1,
451 $ ldq, qc, ldqc, zero, work, n )
452 CALL slacpy(
'ALL', n, nblock, work, n, q( 1, k+1 ),
458 sheight = k-istartm+1
460 IF ( sheight > 0 )
THEN
461 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one,
462 $ a( istartm, k ), lda, zc, ldzc, zero, work,
464 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
465 $ a( istartm, k ), lda )
466 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one,
467 $ b( istartm, k ), ldb, zc, ldzc, zero, work,
469 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
470 $ b( istartm, k ), ldb )
473 CALL sgemm(
'N',
'N', n, nblock, nblock, one, z( 1, k ),
474 $ ldz, zc, ldzc, zero, work, n )
475 CALL slacpy(
'ALL', n, nblock, work, n, z( 1, k ), ldz )
485 CALL slaset(
'FULL', ns, ns, zero, one, qc, ldqc )
486 CALL slaset(
'FULL', ns+1, ns+1, zero, one, zc, ldzc )
495 DO ishift = ihi-i-1, ihi-2
496 CALL slaqz2( .true., .true., ishift, istartb, istopb,
498 $ a, lda, b, ldb, ns, ihi-ns+1, qc, ldqc, ns+1,
509 swidth = istopm-( ihi+1 )+1
510 IF ( swidth > 0 )
THEN
511 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc,
513 $ a( ihi-ns+1, ihi+1 ), lda, zero, work, sheight )
514 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
515 $ a( ihi-ns+1, ihi+1 ), lda )
516 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc,
518 $ b( ihi-ns+1, ihi+1 ), ldb, zero, work, sheight )
519 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
520 $ b( ihi-ns+1, ihi+1 ), ldb )
523 CALL sgemm(
'N',
'N', n, ns, ns, one, q( 1, ihi-ns+1 ), ldq,
524 $ qc, ldqc, zero, work, n )
525 CALL slacpy(
'ALL', n, ns, work, n, q( 1, ihi-ns+1 ), ldq )
530 sheight = ihi-ns-istartm+1
532 IF ( sheight > 0 )
THEN
533 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one,
535 $ ihi-ns ), lda, zc, ldzc, zero, work, sheight )
536 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
539 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one,
541 $ ihi-ns ), ldb, zc, ldzc, zero, work, sheight )
542 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
547 CALL sgemm(
'N',
'N', n, ns+1, ns+1, one, z( 1, ihi-ns ), ldz,
549 $ ldzc, zero, work, n )
550 CALL slacpy(
'ALL', n, ns+1, work, n, z( 1, ihi-ns ), ldz )