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

◆ claqz3()

subroutine claqz3 ( 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) nshifts,
integer, intent(in) nblock_desired,
complex, dimension( * ), intent(inout) alpha,
complex, dimension( * ), intent(inout) beta,
complex, dimension( lda, * ), intent(inout) a,
integer, intent(in) lda,
complex, dimension( ldb, * ), intent(inout) b,
integer, intent(in) ldb,
complex, dimension( ldq, * ), intent(inout) q,
integer, intent(in) ldq,
complex, dimension( ldz, * ), intent(inout) z,
integer, intent(in) ldz,
complex, dimension( ldqc, * ), intent(inout) qc,
integer, intent(in) ldqc,
complex, dimension( ldzc, * ), intent(inout) zc,
integer, intent(in) ldzc,
complex, dimension( * ), intent(inout) work,
integer, intent(in) lwork,
integer, intent(out) info )

CLAQZ3

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

Purpose:
!>
!> CLAQZ3 Executes a single multishift QZ sweep
!> 
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
!> 
[in]NSHIFTS
!>          NSHIFTS is INTEGER
!>          The desired number of shifts to use
!> 
[in]NBLOCK_DESIRED
!>          NBLOCK_DESIRED is INTEGER
!>          The desired size of the computational windows
!> 
[in]ALPHA
!>          ALPHA is COMPLEX array. SR contains
!>          the alpha parts of the shifts to use.
!> 
[in]BETA
!>          BETA is COMPLEX array. SS contains
!>          the scale of the shifts to use.
!> 
[in,out]A
!>          A is COMPLEX 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 COMPLEX 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 COMPLEX array, dimension (LDQ, N)
!> 
[in]LDQ
!>          LDQ is INTEGER
!> 
[in,out]Z
!>          Z is COMPLEX array, dimension (LDZ, N)
!> 
[in]LDZ
!>          LDZ is INTEGER
!> 
[in,out]QC
!>          QC is COMPLEX array, dimension (LDQC, NBLOCK_DESIRED)
!> 
[in]LDQC
!>          LDQC is INTEGER
!> 
[in,out]ZC
!>          ZC is COMPLEX array, dimension (LDZC, NBLOCK_DESIRED)
!> 
[in]LDZC
!>          LDZ is INTEGER
!> 
[out]WORK
!>          WORK is COMPLEX 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.
!> 
[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 201 of file claqz3.f.

205 IMPLICIT NONE
206
207* Function arguments
208 LOGICAL, INTENT( IN ) :: ILSCHUR, ILQ, ILZ
209 INTEGER, INTENT( IN ) :: N, ILO, IHI, LDA, LDB, LDQ, LDZ, LWORK,
210 $ NSHIFTS, NBLOCK_DESIRED, LDQC, LDZC
211
212 COMPLEX, INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
213 $ Z( LDZ, * ), QC( LDQC, * ), ZC( LDZC, * ), WORK( * ),
214 $ ALPHA( * ), BETA( * )
215
216 INTEGER, INTENT( OUT ) :: INFO
217
218* Parameters
219 COMPLEX CZERO, CONE
220 parameter( czero = ( 0.0, 0.0 ), cone = ( 1.0, 0.0 ) )
221 REAL :: ZERO, ONE, HALF
222 parameter( zero = 0.0, one = 1.0, half = 0.5 )
223
224* Local scalars
225 INTEGER :: I, J, NS, ISTARTM, ISTOPM, SHEIGHT, SWIDTH, K, NP,
226 $ ISTARTB, ISTOPB, ISHIFT, NBLOCK, NPOS
227 REAL :: SAFMIN, SAFMAX, C, SCALE
228 COMPLEX :: TEMP, TEMP2, TEMP3, S
229
230* External Functions
231 EXTERNAL :: xerbla, claset, clartg, crot,
233 REAL, EXTERNAL :: SLAMCH
234
235 info = 0
236 IF ( nblock_desired .LT. nshifts+1 ) THEN
237 info = -8
238 END IF
239 IF ( lwork .EQ.-1 ) THEN
240* workspace query, quick return
241 work( 1 ) = cmplx( n*nblock_desired )
242 RETURN
243 ELSE IF ( lwork .LT. n*nblock_desired ) THEN
244 info = -25
245 END IF
246
247 IF( info.NE.0 ) THEN
248 CALL xerbla( 'CLAQZ3', -info )
249 RETURN
250 END IF
251
252*
253* Executable statements
254*
255
256* Get machine constants
257 safmin = slamch( 'SAFE MINIMUM' )
258 safmax = one/safmin
259
260 IF ( ilo .GE. ihi ) THEN
261 RETURN
262 END IF
263
264 IF ( ilschur ) THEN
265 istartm = 1
266 istopm = n
267 ELSE
268 istartm = ilo
269 istopm = ihi
270 END IF
271
272 ns = nshifts
273 npos = max( nblock_desired-ns, 1 )
274
275
276* The following block introduces the shifts and chases
277* them down one by one just enough to make space for
278* the other shifts. The near-the-diagonal block is
279* of size (ns+1) x ns.
280
281 CALL claset( 'FULL', ns+1, ns+1, czero, cone, qc, ldqc )
282 CALL claset( 'FULL', ns, ns, czero, cone, zc, ldzc )
283
284 DO i = 1, ns
285* Introduce the shift
286 scale = sqrt( abs( alpha( i ) ) ) * sqrt( abs( beta( i ) ) )
287 IF( scale .GE. safmin .AND. scale .LE. safmax ) THEN
288 alpha( i ) = alpha( i )/scale
289 beta( i ) = beta( i )/scale
290 END IF
291
292 temp2 = beta( i )*a( ilo, ilo )-alpha( i )*b( ilo, ilo )
293 temp3 = beta( i )*a( ilo+1, ilo )
294
295 IF ( abs( temp2 ) .GT. safmax .OR.
296 $ abs( temp3 ) .GT. safmax ) THEN
297 temp2 = cone
298 temp3 = czero
299 END IF
300
301 CALL clartg( temp2, temp3, c, s, temp )
302 CALL crot( ns, a( ilo, ilo ), lda, a( ilo+1, ilo ), lda,
303 $ c, s )
304 CALL crot( ns, b( ilo, ilo ), ldb, b( ilo+1, ilo ), ldb,
305 $ c, s )
306 CALL crot( ns+1, qc( 1, 1 ), 1, qc( 1, 2 ), 1, c,
307 $ conjg( s ) )
308
309* Chase the shift down
310 DO j = 1, ns-i
311
312 CALL claqz1( .true., .true., j, 1, ns, ihi-ilo+1, a( ilo,
313 $ ilo ), lda, b( ilo, ilo ), ldb, ns+1, 1, qc,
314 $ ldqc, ns, 1, zc, ldzc )
315
316 END DO
317
318 END DO
319
320* Update the rest of the pencil
321
322* Update A(ilo:ilo+ns,ilo+ns:istopm) and B(ilo:ilo+ns,ilo+ns:istopm)
323* from the left with Qc(1:ns+1,1:ns+1)'
324 sheight = ns+1
325 swidth = istopm-( ilo+ns )+1
326 IF ( swidth > 0 ) THEN
327 CALL cgemm( 'C', 'N', sheight, swidth, sheight, cone, qc,
328 $ ldqc,
329 $ a( ilo, ilo+ns ), lda, czero, work, sheight )
330 CALL clacpy( 'ALL', sheight, swidth, work, sheight, a( ilo,
331 $ ilo+ns ), lda )
332 CALL cgemm( 'C', 'N', sheight, swidth, sheight, cone, qc,
333 $ ldqc,
334 $ b( ilo, ilo+ns ), ldb, czero, work, sheight )
335 CALL clacpy( 'ALL', sheight, swidth, work, sheight, b( ilo,
336 $ ilo+ns ), ldb )
337 END IF
338 IF ( ilq ) THEN
339 CALL cgemm( 'N', 'N', n, sheight, sheight, cone, q( 1, ilo ),
340 $ ldq, qc, ldqc, czero, work, n )
341 CALL clacpy( 'ALL', n, sheight, work, n, q( 1, ilo ), ldq )
342 END IF
343
344* Update A(istartm:ilo-1,ilo:ilo+ns-1) and B(istartm:ilo-1,ilo:ilo+ns-1)
345* from the right with Zc(1:ns,1:ns)
346 sheight = ilo-1-istartm+1
347 swidth = ns
348 IF ( sheight > 0 ) THEN
349 CALL cgemm( 'N', 'N', sheight, swidth, swidth, cone,
350 $ a( istartm, ilo ), lda, zc, ldzc, czero, work,
351 $ sheight )
352 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
353 $ a( istartm,
354 $ ilo ), lda )
355 CALL cgemm( 'N', 'N', sheight, swidth, swidth, cone,
356 $ b( istartm, ilo ), ldb, zc, ldzc, czero, work,
357 $ sheight )
358 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
359 $ b( istartm,
360 $ ilo ), ldb )
361 END IF
362 IF ( ilz ) THEN
363 CALL cgemm( 'N', 'N', n, swidth, swidth, cone, z( 1, ilo ),
364 $ ldz, zc, ldzc, czero, work, n )
365 CALL clacpy( 'ALL', n, swidth, work, n, z( 1, ilo ), ldz )
366 END IF
367
368* The following block chases the shifts down to the bottom
369* right block. If possible, a shift is moved down npos
370* positions at a time
371
372 k = ilo
373 DO WHILE ( k < ihi-ns )
374 np = min( ihi-ns-k, npos )
375* Size of the near-the-diagonal block
376 nblock = ns+np
377* istartb points to the first row we will be updating
378 istartb = k+1
379* istopb points to the last column we will be updating
380 istopb = k+nblock-1
381
382 CALL claset( 'FULL', ns+np, ns+np, czero, cone, qc, ldqc )
383 CALL claset( 'FULL', ns+np, ns+np, czero, cone, zc, ldzc )
384
385* Near the diagonal shift chase
386 DO i = ns-1, 0, -1
387 DO j = 0, np-1
388* Move down the block with index k+i+j, updating
389* the (ns+np x ns+np) block:
390* (k:k+ns+np,k:k+ns+np-1)
391 CALL claqz1( .true., .true., k+i+j, istartb, istopb,
392 $ ihi,
393 $ a, lda, b, ldb, nblock, k+1, qc, ldqc,
394 $ nblock, k, zc, ldzc )
395 END DO
396 END DO
397
398* Update rest of the pencil
399
400* Update A(k+1:k+ns+np, k+ns+np:istopm) and
401* B(k+1:k+ns+np, k+ns+np:istopm)
402* from the left with Qc(1:ns+np,1:ns+np)'
403 sheight = ns+np
404 swidth = istopm-( k+ns+np )+1
405 IF ( swidth > 0 ) THEN
406 CALL cgemm( 'C', 'N', sheight, swidth, sheight, cone, qc,
407 $ ldqc, a( k+1, k+ns+np ), lda, czero, work,
408 $ sheight )
409 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
410 $ a( k+1,
411 $ k+ns+np ), lda )
412 CALL cgemm( 'C', 'N', sheight, swidth, sheight, cone, qc,
413 $ ldqc, b( k+1, k+ns+np ), ldb, czero, work,
414 $ sheight )
415 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
416 $ b( k+1,
417 $ k+ns+np ), ldb )
418 END IF
419 IF ( ilq ) THEN
420 CALL cgemm( 'N', 'N', n, nblock, nblock, cone, q( 1,
421 $ k+1 ),
422 $ ldq, qc, ldqc, czero, work, n )
423 CALL clacpy( 'ALL', n, nblock, work, n, q( 1, k+1 ),
424 $ ldq )
425 END IF
426
427* Update A(istartm:k,k:k+ns+npos-1) and B(istartm:k,k:k+ns+npos-1)
428* from the right with Zc(1:ns+np,1:ns+np)
429 sheight = k-istartm+1
430 swidth = nblock
431 IF ( sheight > 0 ) THEN
432 CALL cgemm( 'N', 'N', sheight, swidth, swidth, cone,
433 $ a( istartm, k ), lda, zc, ldzc, czero, work,
434 $ sheight )
435 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
436 $ a( istartm, k ), lda )
437 CALL cgemm( 'N', 'N', sheight, swidth, swidth, cone,
438 $ b( istartm, k ), ldb, zc, ldzc, czero, work,
439 $ sheight )
440 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
441 $ b( istartm, k ), ldb )
442 END IF
443 IF ( ilz ) THEN
444 CALL cgemm( 'N', 'N', n, nblock, nblock, cone, z( 1, k ),
445 $ ldz, zc, ldzc, czero, work, n )
446 CALL clacpy( 'ALL', n, nblock, work, n, z( 1, k ), ldz )
447 END IF
448
449 k = k+np
450
451 END DO
452
453* The following block removes the shifts from the bottom right corner
454* one by one. Updates are initially applied to A(ihi-ns+1:ihi,ihi-ns:ihi).
455
456 CALL claset( 'FULL', ns, ns, czero, cone, qc, ldqc )
457 CALL claset( 'FULL', ns+1, ns+1, czero, cone, zc, ldzc )
458
459* istartb points to the first row we will be updating
460 istartb = ihi-ns+1
461* istopb points to the last column we will be updating
462 istopb = ihi
463
464 DO i = 1, ns
465* Chase the shift down to the bottom right corner
466 DO ishift = ihi-i, ihi-1
467 CALL claqz1( .true., .true., ishift, istartb, istopb,
468 $ ihi,
469 $ a, lda, b, ldb, ns, ihi-ns+1, qc, ldqc, ns+1,
470 $ ihi-ns, zc, ldzc )
471 END DO
472
473 END DO
474
475* Update rest of the pencil
476
477* Update A(ihi-ns+1:ihi, ihi+1:istopm)
478* from the left with Qc(1:ns,1:ns)'
479 sheight = ns
480 swidth = istopm-( ihi+1 )+1
481 IF ( swidth > 0 ) THEN
482 CALL cgemm( 'C', 'N', sheight, swidth, sheight, cone, qc,
483 $ ldqc,
484 $ a( ihi-ns+1, ihi+1 ), lda, czero, work, sheight )
485 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
486 $ a( ihi-ns+1, ihi+1 ), lda )
487 CALL cgemm( 'C', 'N', sheight, swidth, sheight, cone, qc,
488 $ ldqc,
489 $ b( ihi-ns+1, ihi+1 ), ldb, czero, work, sheight )
490 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
491 $ b( ihi-ns+1, ihi+1 ), ldb )
492 END IF
493 IF ( ilq ) THEN
494 CALL cgemm( 'N', 'N', n, ns, ns, cone, q( 1, ihi-ns+1 ),
495 $ ldq,
496 $ qc, ldqc, czero, work, n )
497 CALL clacpy( 'ALL', n, ns, work, n, q( 1, ihi-ns+1 ), ldq )
498 END IF
499
500* Update A(istartm:ihi-ns,ihi-ns:ihi)
501* from the right with Zc(1:ns+1,1:ns+1)
502 sheight = ihi-ns-istartm+1
503 swidth = ns+1
504 IF ( sheight > 0 ) THEN
505 CALL cgemm( 'N', 'N', sheight, swidth, swidth, cone,
506 $ a( istartm, ihi-ns ), lda, zc, ldzc, czero, work,
507 $ sheight )
508 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
509 $ a( istartm,
510 $ ihi-ns ), lda )
511 CALL cgemm( 'N', 'N', sheight, swidth, swidth, cone,
512 $ b( istartm, ihi-ns ), ldb, zc, ldzc, czero, work,
513 $ sheight )
514 CALL clacpy( 'ALL', sheight, swidth, work, sheight,
515 $ b( istartm,
516 $ ihi-ns ), ldb )
517 END IF
518 IF ( ilz ) THEN
519 CALL cgemm( 'N', 'N', n, ns+1, ns+1, cone, z( 1, ihi-ns ),
520 $ ldz,
521 $ zc, ldzc, czero, work, n )
522 CALL clacpy( 'ALL', n, ns+1, work, n, z( 1, ihi-ns ), ldz )
523 END IF
524
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
Definition cgemm.f:188
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
Definition clacpy.f:101
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
subroutine claqz1(ilq, ilz, k, istartm, istopm, ihi, a, lda, b, ldb, nq, qstart, q, ldq, nz, zstart, z, ldz)
CLAQZ1
Definition claqz1.f:172
subroutine clartg(f, g, c, s, r)
CLARTG generates a plane rotation with real cosine and complex sine.
Definition clartg.f90:116
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition claset.f:104
subroutine crot(n, cx, incx, cy, incy, c, s)
CROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.
Definition crot.f:101
Here is the call graph for this function:
Here is the caller graph for this function: