LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ slaqz3()

recursive subroutine slaqz3 ( logical, intent(in) ilschur,
logical, intent(in) ilq,
logical, intent(in) ilz,
integer, intent(in) n,
integer, intent(in) ilo,
integer, intent(in) ihi,
integer, intent(in) nw,
real, dimension( lda, * ), intent(inout) a,
integer, intent(in) lda,
real, dimension( ldb, * ), intent(inout) b,
integer, intent(in) ldb,
real, dimension( ldq, * ), intent(inout) q,
integer, intent(in) ldq,
real, dimension( ldz, * ), intent(inout) z,
integer, intent(in) ldz,
integer, intent(out) ns,
integer, intent(out) nd,
real, dimension( * ), intent(inout) alphar,
real, dimension( * ), intent(inout) alphai,
real, dimension( * ), intent(inout) beta,
real, dimension( ldqc, * ) qc,
integer, intent(in) ldqc,
real, dimension( ldzc, * ) zc,
integer, intent(in) ldzc,
real, dimension( * ) work,
integer, intent(in) lwork,
integer, intent(in) rec,
integer, intent(out) info )

SLAQZ3

Download SLAQZ3 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAQZ3 performs AED
!> 
Parameters
[in]ILSCHUR
!>          ILSCHUR is LOGICAL
!>              Determines whether or not to update the full Schur form
!> 
[in]ILQ
!>          ILQ is LOGICAL
!>              Determines whether or not to update the matrix Q
!> 
[in]ILZ
!>          ILZ is LOGICAL
!>              Determines whether or not to update the matrix Z
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrices A, B, Q, and Z.  N >= 0.
!> 
[in]ILO
!>          ILO is INTEGER
!> 
[in]IHI
!>          IHI is INTEGER
!>          ILO and IHI mark the rows and columns of (A,B) which
!>          are to be normalized
!> 
[in]NW
!>          NW is INTEGER
!>          The desired size of the deflation window.
!> 
[in,out]A
!>          A is REAL array, dimension (LDA, N)
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max( 1, N ).
!> 
[in,out]B
!>          B is REAL array, dimension (LDB, N)
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B.  LDB >= max( 1, N ).
!> 
[in,out]Q
!>          Q is REAL array, dimension (LDQ, N)
!> 
[in]LDQ
!>          LDQ is INTEGER
!> 
[in,out]Z
!>          Z is REAL array, dimension (LDZ, N)
!> 
[in]LDZ
!>          LDZ is INTEGER
!> 
[out]NS
!>          NS is INTEGER
!>          The number of unconverged eigenvalues available to
!>          use as shifts.
!> 
[out]ND
!>          ND is INTEGER
!>          The number of converged eigenvalues found.
!> 
[out]ALPHAR
!>          ALPHAR is REAL array, dimension (N)
!>          The real parts of each scalar alpha defining an eigenvalue
!>          of GNEP.
!> 
[out]ALPHAI
!>          ALPHAI is REAL array, dimension (N)
!>          The imaginary parts of each scalar alpha defining an
!>          eigenvalue of GNEP.
!>          If ALPHAI(j) is zero, then the j-th eigenvalue is real; if
!>          positive, then the j-th and (j+1)-st eigenvalues are a
!>          complex conjugate pair, with ALPHAI(j+1) = -ALPHAI(j).
!> 
[out]BETA
!>          BETA is REAL array, dimension (N)
!>          The scalars beta that define the eigenvalues of GNEP.
!>          Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and
!>          beta = BETA(j) represent the j-th eigenvalue of the matrix
!>          pair (A,B), in one of the forms lambda = alpha/beta or
!>          mu = beta/alpha.  Since either lambda or mu may overflow,
!>          they should not, in general, be computed.
!> 
[in,out]QC
!>          QC is REAL array, dimension (LDQC, NW)
!> 
[in]LDQC
!>          LDQC is INTEGER
!> 
[in,out]ZC
!>          ZC is REAL array, dimension (LDZC, NW)
!> 
[in]LDZC
!>          LDZ is INTEGER
!> 
[out]WORK
!>          WORK is REAL array, dimension (MAX(1,LWORK))
!>          On exit, if INFO >= 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The dimension of the array WORK.  LWORK >= max(1,N).
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[in]REC
!>          REC is INTEGER
!>             REC indicates the current recursion level. Should be set
!>             to 0 on first call.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0: successful exit
!>          < 0: if INFO = -i, the i-th argument had an illegal value
!> 
Author
Thijs Steel, KU Leuven
Date
May 2020

Definition at line 232 of file slaqz3.f.

237 IMPLICIT NONE
238
239* Arguments
240 LOGICAL, INTENT( IN ) :: ILSCHUR, ILQ, ILZ
241 INTEGER, INTENT( IN ) :: N, ILO, IHI, NW, LDA, LDB, LDQ, LDZ,
242 $ LDQC, LDZC, LWORK, REC
243
244 REAL, INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
245 $ Z( LDZ, * ), ALPHAR( * ), ALPHAI( * ), BETA( * )
246 INTEGER, INTENT( OUT ) :: NS, ND, INFO
247 REAL :: QC( LDQC, * ), ZC( LDZC, * ), WORK( * )
248
249* Parameters
250 REAL :: ZERO, ONE, HALF
251 parameter( zero = 0.0, one = 1.0, half = 0.5 )
252
253* Local Scalars
254 LOGICAL :: BULGE
255 INTEGER :: JW, KWTOP, KWBOT, ISTOPM, ISTARTM, K, K2, STGEXC_INFO,
256 $ IFST, ILST, LWORKREQ, QZ_SMALL_INFO
257 REAL :: S, SMLNUM, ULP, SAFMIN, SAFMAX, C1, S1, TEMP
258
259* External Functions
260 EXTERNAL :: xerbla, stgexc, slaqz0, slacpy, slaset,
262 REAL, EXTERNAL :: SLAMCH, SROUNDUP_LWORK
263
264 info = 0
265
266* Set up deflation window
267 jw = min( nw, ihi-ilo+1 )
268 kwtop = ihi-jw+1
269 IF ( kwtop .EQ. ilo ) THEN
270 s = zero
271 ELSE
272 s = a( kwtop, kwtop-1 )
273 END IF
274
275* Determine required workspace
276 ifst = 1
277 ilst = jw
278 CALL stgexc( .true., .true., jw, a, lda, b, ldb, qc, ldqc, zc,
279 $ ldzc, ifst, ilst, work, -1, stgexc_info )
280 lworkreq = int( work( 1 ) )
281 CALL slaqz0( 'S', 'V', 'V', jw, 1, jw, a( kwtop, kwtop ), lda,
282 $ b( kwtop, kwtop ), ldb, alphar, alphai, beta, qc,
283 $ ldqc, zc, ldzc, work, -1, rec+1, qz_small_info )
284 lworkreq = max( lworkreq, int( work( 1 ) )+2*jw**2 )
285 lworkreq = max( lworkreq, n*nw, 2*nw**2+n )
286 IF ( lwork .EQ.-1 ) THEN
287* workspace query, quick return
288 work( 1 ) = sroundup_lwork(lworkreq)
289 RETURN
290 ELSE IF ( lwork .LT. lworkreq ) THEN
291 info = -26
292 END IF
293
294 IF( info.NE.0 ) THEN
295 CALL xerbla( 'SLAQZ3', -info )
296 RETURN
297 END IF
298
299* Get machine constants
300 safmin = slamch( 'SAFE MINIMUM' )
301 safmax = one/safmin
302 ulp = slamch( 'PRECISION' )
303 smlnum = safmin*( real( n )/ulp )
304
305 IF ( ihi .EQ. kwtop ) THEN
306* 1 by 1 deflation window, just try a regular deflation
307 alphar( kwtop ) = a( kwtop, kwtop )
308 alphai( kwtop ) = zero
309 beta( kwtop ) = b( kwtop, kwtop )
310 ns = 1
311 nd = 0
312 IF ( abs( s ) .LE. max( smlnum, ulp*abs( a( kwtop,
313 $ kwtop ) ) ) ) THEN
314 ns = 0
315 nd = 1
316 IF ( kwtop .GT. ilo ) THEN
317 a( kwtop, kwtop-1 ) = zero
318 END IF
319 END IF
320 END IF
321
322
323* Store window in case of convergence failure
324 CALL slacpy( 'ALL', jw, jw, a( kwtop, kwtop ), lda, work, jw )
325 CALL slacpy( 'ALL', jw, jw, b( kwtop, kwtop ), ldb,
326 $ work( jw**2+
327 $ 1 ), jw )
328
329* Transform window to real schur form
330 CALL slaset( 'FULL', jw, jw, zero, one, qc, ldqc )
331 CALL slaset( 'FULL', jw, jw, zero, one, zc, ldzc )
332 CALL slaqz0( 'S', 'V', 'V', jw, 1, jw, a( kwtop, kwtop ), lda,
333 $ b( kwtop, kwtop ), ldb, alphar, alphai, beta, qc,
334 $ ldqc, zc, ldzc, work( 2*jw**2+1 ), lwork-2*jw**2,
335 $ rec+1, qz_small_info )
336
337 IF( qz_small_info .NE. 0 ) THEN
338* Convergence failure, restore the window and exit
339 nd = 0
340 ns = jw-qz_small_info
341 CALL slacpy( 'ALL', jw, jw, work, jw, a( kwtop, kwtop ),
342 $ lda )
343 CALL slacpy( 'ALL', jw, jw, work( jw**2+1 ), jw, b( kwtop,
344 $ kwtop ), ldb )
345 RETURN
346 END IF
347
348* Deflation detection loop
349 IF ( kwtop .EQ. ilo .OR. s .EQ. zero ) THEN
350 kwbot = kwtop-1
351 ELSE
352 kwbot = ihi
353 k = 1
354 k2 = 1
355 DO WHILE ( k .LE. jw )
356 bulge = .false.
357 IF ( kwbot-kwtop+1 .GE. 2 ) THEN
358 bulge = a( kwbot, kwbot-1 ) .NE. zero
359 END IF
360 IF ( bulge ) THEN
361
362* Try to deflate complex conjugate eigenvalue pair
363 temp = abs( a( kwbot, kwbot ) )+sqrt( abs( a( kwbot,
364 $ kwbot-1 ) ) )*sqrt( abs( a( kwbot-1, kwbot ) ) )
365 IF( temp .EQ. zero )THEN
366 temp = abs( s )
367 END IF
368 IF ( max( abs( s*qc( 1, kwbot-kwtop ) ), abs( s*qc( 1,
369 $ kwbot-kwtop+1 ) ) ) .LE. max( smlnum,
370 $ ulp*temp ) ) THEN
371* Deflatable
372 kwbot = kwbot-2
373 ELSE
374* Not deflatable, move out of the way
375 ifst = kwbot-kwtop+1
376 ilst = k2
377 CALL stgexc( .true., .true., jw, a( kwtop, kwtop ),
378 $ lda, b( kwtop, kwtop ), ldb, qc, ldqc,
379 $ zc, ldzc, ifst, ilst, work, lwork,
380 $ stgexc_info )
381 k2 = k2+2
382 END IF
383 k = k+2
384 ELSE
385
386* Try to deflate real eigenvalue
387 temp = abs( a( kwbot, kwbot ) )
388 IF( temp .EQ. zero ) THEN
389 temp = abs( s )
390 END IF
391 IF ( ( abs( s*qc( 1, kwbot-kwtop+1 ) ) ) .LE. max( ulp*
392 $ temp, smlnum ) ) THEN
393* Deflatable
394 kwbot = kwbot-1
395 ELSE
396* Not deflatable, move out of the way
397 ifst = kwbot-kwtop+1
398 ilst = k2
399 CALL stgexc( .true., .true., jw, a( kwtop, kwtop ),
400 $ lda, b( kwtop, kwtop ), ldb, qc, ldqc,
401 $ zc, ldzc, ifst, ilst, work, lwork,
402 $ stgexc_info )
403 k2 = k2+1
404 END IF
405
406 k = k+1
407
408 END IF
409 END DO
410 END IF
411
412* Store eigenvalues
413 nd = ihi-kwbot
414 ns = jw-nd
415 k = kwtop
416 DO WHILE ( k .LE. ihi )
417 bulge = .false.
418 IF ( k .LT. ihi ) THEN
419 IF ( a( k+1, k ) .NE. zero ) THEN
420 bulge = .true.
421 END IF
422 END IF
423 IF ( bulge ) THEN
424* 2x2 eigenvalue block
425 CALL slag2( a( k, k ), lda, b( k, k ), ldb, safmin,
426 $ beta( k ), beta( k+1 ), alphar( k ),
427 $ alphar( k+1 ), alphai( k ) )
428 alphai( k+1 ) = -alphai( k )
429 k = k+2
430 ELSE
431* 1x1 eigenvalue block
432 alphar( k ) = a( k, k )
433 alphai( k ) = zero
434 beta( k ) = b( k, k )
435 k = k+1
436 END IF
437 END DO
438
439 IF ( kwtop .NE. ilo .AND. s .NE. zero ) THEN
440* Reflect spike back, this will create optimally packed bulges
441 a( kwtop:kwbot, kwtop-1 ) = a( kwtop, kwtop-1 )*qc( 1,
442 $ 1:jw-nd )
443 DO k = kwbot-1, kwtop, -1
444 CALL slartg( a( k, kwtop-1 ), a( k+1, kwtop-1 ), c1, s1,
445 $ temp )
446 a( k, kwtop-1 ) = temp
447 a( k+1, kwtop-1 ) = zero
448 k2 = max( kwtop, k-1 )
449 CALL srot( ihi-k2+1, a( k, k2 ), lda, a( k+1, k2 ), lda,
450 $ c1,
451 $ s1 )
452 CALL srot( ihi-( k-1 )+1, b( k, k-1 ), ldb, b( k+1,
453 $ k-1 ),
454 $ ldb, c1, s1 )
455 CALL srot( jw, qc( 1, k-kwtop+1 ), 1, qc( 1,
456 $ k+1-kwtop+1 ),
457 $ 1, c1, s1 )
458 END DO
459
460* Chase bulges down
461 istartm = kwtop
462 istopm = ihi
463 k = kwbot-1
464 DO WHILE ( k .GE. kwtop )
465 IF ( ( k .GE. kwtop+1 ) .AND. a( k+1, k-1 ) .NE. zero ) THEN
466
467* Move double pole block down and remove it
468 DO k2 = k-1, kwbot-2
469 CALL slaqz2( .true., .true., k2, kwtop, kwtop+jw-1,
470 $ kwbot, a, lda, b, ldb, jw, kwtop, qc,
471 $ ldqc, jw, kwtop, zc, ldzc )
472 END DO
473
474 k = k-2
475 ELSE
476
477* k points to single shift
478 DO k2 = k, kwbot-2
479
480* Move shift down
481 CALL slartg( b( k2+1, k2+1 ), b( k2+1, k2 ), c1,
482 $ s1,
483 $ temp )
484 b( k2+1, k2+1 ) = temp
485 b( k2+1, k2 ) = zero
486 CALL srot( k2+2-istartm+1, a( istartm, k2+1 ), 1,
487 $ a( istartm, k2 ), 1, c1, s1 )
488 CALL srot( k2-istartm+1, b( istartm, k2+1 ), 1,
489 $ b( istartm, k2 ), 1, c1, s1 )
490 CALL srot( jw, zc( 1, k2+1-kwtop+1 ), 1, zc( 1,
491 $ k2-kwtop+1 ), 1, c1, s1 )
492
493 CALL slartg( a( k2+1, k2 ), a( k2+2, k2 ), c1, s1,
494 $ temp )
495 a( k2+1, k2 ) = temp
496 a( k2+2, k2 ) = zero
497 CALL srot( istopm-k2, a( k2+1, k2+1 ), lda,
498 $ a( k2+2,
499 $ k2+1 ), lda, c1, s1 )
500 CALL srot( istopm-k2, b( k2+1, k2+1 ), ldb,
501 $ b( k2+2,
502 $ k2+1 ), ldb, c1, s1 )
503 CALL srot( jw, qc( 1, k2+1-kwtop+1 ), 1, qc( 1,
504 $ k2+2-kwtop+1 ), 1, c1, s1 )
505
506 END DO
507
508* Remove the shift
509 CALL slartg( b( kwbot, kwbot ), b( kwbot, kwbot-1 ),
510 $ c1,
511 $ s1, temp )
512 b( kwbot, kwbot ) = temp
513 b( kwbot, kwbot-1 ) = zero
514 CALL srot( kwbot-istartm, b( istartm, kwbot ), 1,
515 $ b( istartm, kwbot-1 ), 1, c1, s1 )
516 CALL srot( kwbot-istartm+1, a( istartm, kwbot ), 1,
517 $ a( istartm, kwbot-1 ), 1, c1, s1 )
518 CALL srot( jw, zc( 1, kwbot-kwtop+1 ), 1, zc( 1,
519 $ kwbot-1-kwtop+1 ), 1, c1, s1 )
520
521 k = k-1
522 END IF
523 END DO
524
525 END IF
526
527* Apply Qc and Zc to rest of the matrix
528 IF ( ilschur ) THEN
529 istartm = 1
530 istopm = n
531 ELSE
532 istartm = ilo
533 istopm = ihi
534 END IF
535
536 IF ( istopm-ihi > 0 ) THEN
537 CALL sgemm( 'T', 'N', jw, istopm-ihi, jw, one, qc, ldqc,
538 $ a( kwtop, ihi+1 ), lda, zero, work, jw )
539 CALL slacpy( 'ALL', jw, istopm-ihi, work, jw, a( kwtop,
540 $ ihi+1 ), lda )
541 CALL sgemm( 'T', 'N', jw, istopm-ihi, jw, one, qc, ldqc,
542 $ b( kwtop, ihi+1 ), ldb, zero, work, jw )
543 CALL slacpy( 'ALL', jw, istopm-ihi, work, jw, b( kwtop,
544 $ ihi+1 ), ldb )
545 END IF
546 IF ( ilq ) THEN
547 CALL sgemm( 'N', 'N', n, jw, jw, one, q( 1, kwtop ), ldq,
548 $ qc,
549 $ ldqc, zero, work, n )
550 CALL slacpy( 'ALL', n, jw, work, n, q( 1, kwtop ), ldq )
551 END IF
552
553 IF ( kwtop-1-istartm+1 > 0 ) THEN
554 CALL sgemm( 'N', 'N', kwtop-istartm, jw, jw, one,
555 $ a( istartm,
556 $ kwtop ), lda, zc, ldzc, zero, work,
557 $ kwtop-istartm )
558 CALL slacpy( 'ALL', kwtop-istartm, jw, work, kwtop-istartm,
559 $ a( istartm, kwtop ), lda )
560 CALL sgemm( 'N', 'N', kwtop-istartm, jw, jw, one,
561 $ b( istartm,
562 $ kwtop ), ldb, zc, ldzc, zero, work,
563 $ kwtop-istartm )
564 CALL slacpy( 'ALL', kwtop-istartm, jw, work, kwtop-istartm,
565 $ b( istartm, kwtop ), ldb )
566 END IF
567 IF ( ilz ) THEN
568 CALL sgemm( 'N', 'N', n, jw, jw, one, z( 1, kwtop ), ldz,
569 $ zc,
570 $ ldzc, zero, work, n )
571 CALL slacpy( 'ALL', n, jw, work, n, z( 1, kwtop ), ldz )
572 END IF
573
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
Definition sgemm.f:188
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
Definition slacpy.f:101
subroutine slag2(a, lda, b, ldb, safmin, scale1, scale2, wr1, wr2, wi)
SLAG2 computes the eigenvalues of a 2-by-2 generalized eigenvalue problem, with scaling as necessary ...
Definition slag2.f:154
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
recursive subroutine slaqz0(wants, wantq, wantz, n, ilo, ihi, a, lda, b, ldb, alphar, alphai, beta, q, ldq, z, ldz, work, lwork, rec, info)
SLAQZ0
Definition slaqz0.f:303
subroutine slaqz2(ilq, ilz, k, istartm, istopm, ihi, a, lda, b, ldb, nq, qstart, q, ldq, nz, zstart, z, ldz)
SLAQZ2
Definition slaqz2.f:172
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
Definition slartg.f90:111
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.
Definition slaset.f:108
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT
Definition srot.f:92
real function sroundup_lwork(lwork)
SROUNDUP_LWORK
subroutine stgexc(wantq, wantz, n, a, lda, b, ldb, q, ldq, z, ldz, ifst, ilst, work, lwork, info)
STGEXC
Definition stgexc.f:218
Here is the call graph for this function:
Here is the caller graph for this function: