210 SUBROUTINE slaqz4( ILSCHUR, ILQ, ILZ, N, ILO, IHI, NSHIFTS,
211 $ NBLOCK_DESIRED, SR, SI, SS, A, LDA, B, LDB, Q,
212 $ LDQ, Z, LDZ, QC, LDQC, ZC, LDZC, WORK, LWORK,
217 LOGICAL,
INTENT( IN ) :: ILSCHUR, ILQ, ILZ
218 INTEGER,
INTENT( IN ) :: N, ILO, IHI, LDA, LDB, LDQ, LDZ, LWORK,
219 $ NSHIFTS, NBLOCK_DESIRED, LDQC, LDZC
221 REAL,
INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
222 $ Z( LDZ, * ), QC( LDQC, * ), ZC( LDZC, * ), WORK( * ), SR( * ),
225 INTEGER,
INTENT( OUT ) :: INFO
228 REAL :: ZERO, ONE, HALF
229 PARAMETER( ZERO = 0.0, one = 1.0, half = 0.5 )
232 INTEGER :: I, J, NS, ISTARTM, ISTOPM, SHEIGHT, SWIDTH, K, NP,
233 $ ISTARTB, ISTOPB, ISHIFT, NBLOCK, NPOS
234 REAL :: TEMP, V( 3 ), C1, S1, C2, S2, SWAP
239 REAL,
EXTERNAL :: SROUNDUP_LWORK
242 IF ( nblock_desired .LT. nshifts+1 )
THEN
245 IF ( lwork .EQ.-1 )
THEN
247 work( 1 ) = sroundup_lwork(n*nblock_desired)
249 ELSE IF ( lwork .LT. n*nblock_desired )
THEN
254 CALL xerbla(
'SLAQZ4', -info )
260 IF ( nshifts .LT. 2 )
THEN
264 IF ( ilo .GE. ihi )
THEN
281 DO i = 1, nshifts-2, 2
282 IF( si( i ).NE.-si( i+1 ) )
THEN
286 sr( i+1 ) = sr( i+2 )
291 si( i+1 ) = si( i+2 )
296 ss( i+1 ) = ss( i+2 )
306 ns = nshifts-mod( nshifts, 2 )
307 npos = max( nblock_desired-ns, 1 )
314 CALL slaset(
'FULL', ns+1, ns+1, zero, one, qc, ldqc )
315 CALL slaset(
'FULL', ns, ns, zero, one, zc, ldzc )
319 CALL slaqz1( a( ilo, ilo ), lda, b( ilo, ilo ), ldb, sr( i ),
320 $ sr( i+1 ), si( i ), ss( i ), ss( i+1 ), v )
323 CALL slartg( temp, v( 3 ), c1, s1, v( 2 ) )
324 CALL slartg( v( 1 ), v( 2 ), c2, s2, temp )
326 CALL srot( ns, a( ilo+1, ilo ), lda, a( ilo+2, ilo ), lda, c1,
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, c1,
332 CALL srot( ns, b( ilo, ilo ), ldb, b( ilo+1, ilo ), ldb, c2,
334 CALL srot( ns+1, qc( 1, 2 ), 1, qc( 1, 3 ), 1, c1, s1 )
335 CALL srot( ns+1, qc( 1, 1 ), 1, qc( 1, 2 ), 1, c2, s2 )
340 CALL slaqz2( .true., .true., j, 1, ns, ihi-ilo+1, a( ilo,
341 $ ilo ), lda, b( ilo, ilo ), ldb, ns+1, 1, qc,
342 $ ldqc, ns, 1, zc, ldzc )
353 swidth = istopm-( ilo+ns )+1
354 IF ( swidth > 0 )
THEN
355 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc, ldqc,
356 $ a( ilo, ilo+ns ), lda, zero, work, sheight )
357 CALL slacpy(
'ALL', sheight, swidth, work, sheight, a( ilo,
359 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc, ldqc,
360 $ b( ilo, ilo+ns ), ldb, zero, work, sheight )
361 CALL slacpy(
'ALL', sheight, swidth, work, sheight, b( ilo,
365 CALL sgemm(
'N',
'N', n, sheight, sheight, one, q( 1, ilo ),
366 $ ldq, qc, ldqc, zero, work, n )
367 CALL slacpy(
'ALL', n, sheight, work, n, q( 1, ilo ), ldq )
372 sheight = ilo-1-istartm+1
374 IF ( sheight > 0 )
THEN
375 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one, a( istartm,
376 $ ilo ), lda, zc, ldzc, zero, work, sheight )
377 CALL slacpy(
'ALL', sheight, swidth, work, sheight, a( istartm,
379 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one, b( istartm,
380 $ ilo ), ldb, zc, ldzc, zero, work, sheight )
381 CALL slacpy(
'ALL', sheight, swidth, work, sheight, b( istartm,
385 CALL sgemm(
'N',
'N', n, swidth, swidth, one, z( 1, ilo ), ldz,
386 $ zc, ldzc, zero, work, n )
387 CALL slacpy(
'ALL', n, swidth, work, n, z( 1, ilo ), ldz )
395 DO WHILE ( k < ihi-ns )
396 np = min( ihi-ns-k, npos )
404 CALL slaset(
'FULL', ns+np, ns+np, zero, one, qc, ldqc )
405 CALL slaset(
'FULL', ns+np, ns+np, zero, one, zc, ldzc )
413 CALL slaqz2( .true., .true., k+i+j-1, istartb, istopb,
414 $ ihi, a, lda, b, ldb, nblock, k+1, qc, ldqc,
415 $ nblock, k, zc, ldzc )
425 swidth = istopm-( k+ns+np )+1
426 IF ( swidth > 0 )
THEN
427 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc,
428 $ ldqc, a( k+1, k+ns+np ), lda, zero, work,
430 CALL slacpy(
'ALL', sheight, swidth, work, sheight, a( k+1,
432 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc,
433 $ ldqc, b( k+1, k+ns+np ), ldb, zero, work,
435 CALL slacpy(
'ALL', sheight, swidth, work, sheight, b( k+1,
439 CALL sgemm(
'N',
'N', n, nblock, nblock, one, q( 1, k+1 ),
440 $ ldq, qc, ldqc, zero, work, n )
441 CALL slacpy(
'ALL', n, nblock, work, n, q( 1, k+1 ), ldq )
446 sheight = k-istartm+1
448 IF ( sheight > 0 )
THEN
449 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one,
450 $ a( istartm, k ), lda, zc, ldzc, zero, work,
452 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
453 $ a( istartm, k ), lda )
454 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one,
455 $ b( istartm, k ), ldb, zc, ldzc, zero, work,
457 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
458 $ b( istartm, k ), ldb )
461 CALL sgemm(
'N',
'N', n, nblock, nblock, one, z( 1, k ),
462 $ ldz, zc, ldzc, zero, work, n )
463 CALL slacpy(
'ALL', n, nblock, work, n, z( 1, k ), ldz )
473 CALL slaset(
'FULL', ns, ns, zero, one, qc, ldqc )
474 CALL slaset(
'FULL', ns+1, ns+1, zero, one, zc, ldzc )
483 DO ishift = ihi-i-1, ihi-2
484 CALL slaqz2( .true., .true., ishift, istartb, istopb, ihi,
485 $ a, lda, b, ldb, ns, ihi-ns+1, qc, ldqc, ns+1,
496 swidth = istopm-( ihi+1 )+1
497 IF ( swidth > 0 )
THEN
498 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc, ldqc,
499 $ a( ihi-ns+1, ihi+1 ), lda, zero, work, sheight )
500 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
501 $ a( ihi-ns+1, ihi+1 ), lda )
502 CALL sgemm(
'T',
'N', sheight, swidth, sheight, one, qc, ldqc,
503 $ b( ihi-ns+1, ihi+1 ), ldb, zero, work, sheight )
504 CALL slacpy(
'ALL', sheight, swidth, work, sheight,
505 $ b( ihi-ns+1, ihi+1 ), ldb )
508 CALL sgemm(
'N',
'N', n, ns, ns, one, q( 1, ihi-ns+1 ), ldq,
509 $ qc, ldqc, zero, work, n )
510 CALL slacpy(
'ALL', n, ns, work, n, q( 1, ihi-ns+1 ), ldq )
515 sheight = ihi-ns-istartm+1
517 IF ( sheight > 0 )
THEN
518 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one, a( istartm,
519 $ ihi-ns ), lda, zc, ldzc, zero, work, sheight )
520 CALL slacpy(
'ALL', sheight, swidth, work, sheight, a( istartm,
522 CALL sgemm(
'N',
'N', sheight, swidth, swidth, one, b( istartm,
523 $ ihi-ns ), ldb, zc, ldzc, zero, work, sheight )
524 CALL slacpy(
'ALL', sheight, swidth, work, sheight, b( istartm,
528 CALL sgemm(
'N',
'N', n, ns+1, ns+1, one, z( 1, ihi-ns ), ldz, zc,
529 $ ldzc, zero, work, n )
530 CALL slacpy(
'ALL', n, ns+1, work, n, z( 1, ihi-ns ), ldz )
subroutine xerbla(srname, info)
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slaqz1(a, lda, b, ldb, sr1, sr2, si, beta1, beta2, v)
SLAQZ1
subroutine slaqz2(ilq, ilz, k, istartm, istopm, ihi, a, lda, b, ldb, nq, qstart, q, ldq, nz, zstart, z, ldz)
SLAQZ2
subroutine slaqz4(ilschur, ilq, ilz, n, ilo, ihi, nshifts, nblock_desired, sr, si, ss, a, lda, b, ldb, q, ldq, z, ldz, qc, ldqc, zc, ldzc, work, lwork, info)
SLAQZ4
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT