219 SUBROUTINE dtgex2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
220 $ LDZ, J1, N1, N2, WORK, LWORK, INFO )
228 INTEGER INFO, J1, LDA, LDB, LDQ, LDZ, LWORK, N, N1, N2
231 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
232 $ work( * ), z( ldz, * )
240 DOUBLE PRECISION ZERO, ONE
241 parameter( zero = 0.0d+0, one = 1.0d+0 )
242 DOUBLE PRECISION TWENTY
243 parameter( twenty = 2.0d+01 )
245 parameter( ldst = 4 )
247 parameter( wands = .true. )
251 INTEGER I, IDUM, LINFO, M
252 DOUBLE PRECISION BQRA21, BRQA21, DDUM, DNORMA, DNORMB, DSCALE,
253 $ dsum, eps, f, g, sa, sb, scale, smlnum,
257 INTEGER IWORK( LDST + 2 )
258 DOUBLE PRECISION AI( 2 ), AR( 2 ), BE( 2 ), IR( LDST, LDST ),
259 $ ircop( ldst, ldst ), li( ldst, ldst ),
260 $ licop( ldst, ldst ), s( ldst, ldst ),
261 $ scpy( ldst, ldst ), t( ldst, ldst ),
262 $ taul( ldst ), taur( ldst ), tcpy( ldst, ldst )
265 DOUBLE PRECISION DLAMCH
274 INTRINSIC abs, max, sqrt
282 IF( n.LE.1 .OR. n1.LE.0 .OR. n2.LE.0 )
284 IF( n1.GT.n .OR. ( j1+n1 ).GT.n )
287 IF( lwork.LT.max( 1, n*m, m*m*2 ) )
THEN
289 work( 1 ) = max( 1, n*m, m*m*2 )
298 CALL dlaset(
'Full', ldst, ldst, zero, zero, li, ldst )
299 CALL dlaset(
'Full', ldst, ldst, zero, zero, ir, ldst )
300 CALL dlacpy(
'Full', m, m, a( j1, j1 ), lda, s, ldst )
301 CALL dlacpy(
'Full', m, m, b( j1, j1 ), ldb, t, ldst )
306 smlnum = dlamch(
'S' ) / eps
309 CALL dlacpy(
'Full', m, m, s, ldst, work, m )
310 CALL dlassq( m*m, work, 1, dscale, dsum )
311 dnorma = dscale*sqrt( dsum )
314 CALL dlacpy(
'Full', m, m, t, ldst, work, m )
315 CALL dlassq( m*m, work, 1, dscale, dsum )
316 dnormb = dscale*sqrt( dsum )
326 thresha = max( twenty*eps*dnorma, smlnum )
327 threshb = max( twenty*eps*dnormb, smlnum )
336 f = s( 2, 2 )*t( 1, 1 ) - t( 2, 2 )*s( 1, 1 )
337 g = s( 2, 2 )*t( 1, 2 ) - t( 2, 2 )*s( 1, 2 )
338 sa = abs( s( 2, 2 ) ) * abs( t( 1, 1 ) )
339 sb = abs( s( 1, 1 ) ) * abs( t( 2, 2 ) )
340 CALL dlartg( f, g, ir( 1, 2 ), ir( 1, 1 ), ddum )
341 ir( 2, 1 ) = -ir( 1, 2 )
342 ir( 2, 2 ) = ir( 1, 1 )
343 CALL drot( 2, s( 1, 1 ), 1, s( 1, 2 ), 1, ir( 1, 1 ),
345 CALL drot( 2, t( 1, 1 ), 1, t( 1, 2 ), 1, ir( 1, 1 ),
348 CALL dlartg( s( 1, 1 ), s( 2, 1 ), li( 1, 1 ), li( 2, 1 ),
351 CALL dlartg( t( 1, 1 ), t( 2, 1 ), li( 1, 1 ), li( 2, 1 ),
354 CALL drot( 2, s( 1, 1 ), ldst, s( 2, 1 ), ldst, li( 1, 1 ),
356 CALL drot( 2, t( 1, 1 ), ldst, t( 2, 1 ), ldst, li( 1, 1 ),
358 li( 2, 2 ) = li( 1, 1 )
359 li( 1, 2 ) = -li( 2, 1 )
364 weak = abs( s( 2, 1 ) ) .LE. thresha .AND.
365 $ abs( t( 2, 1 ) ) .LE. threshb
376 CALL dlacpy(
'Full', m, m, a( j1, j1 ), lda, work( m*m+1 ),
378 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, s, ldst, zero,
380 CALL dgemm(
'N',
'T', m, m, m, -one, work, m, ir, ldst, one,
384 CALL dlassq( m*m, work( m*m+1 ), 1, dscale, dsum )
385 sa = dscale*sqrt( dsum )
387 CALL dlacpy(
'Full', m, m, b( j1, j1 ), ldb, work( m*m+1 ),
389 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, t, ldst, zero,
391 CALL dgemm(
'N',
'T', m, m, m, -one, work, m, ir, ldst, one,
395 CALL dlassq( m*m, work( m*m+1 ), 1, dscale, dsum )
396 sb = dscale*sqrt( dsum )
397 strong = sa.LE.thresha .AND. sb.LE.threshb
405 CALL drot( j1+1, a( 1, j1 ), 1, a( 1, j1+1 ), 1, ir( 1, 1 ),
407 CALL drot( j1+1, b( 1, j1 ), 1, b( 1, j1+1 ), 1, ir( 1, 1 ),
409 CALL drot( n-j1+1, a( j1, j1 ), lda, a( j1+1, j1 ), lda,
410 $ li( 1, 1 ), li( 2, 1 ) )
411 CALL drot( n-j1+1, b( j1, j1 ), ldb, b( j1+1, j1 ), ldb,
412 $ li( 1, 1 ), li( 2, 1 ) )
422 $
CALL drot( n, z( 1, j1 ), 1, z( 1, j1+1 ), 1, ir( 1, 1 ),
425 $
CALL drot( n, q( 1, j1 ), 1, q( 1, j1+1 ), 1, li( 1, 1 ),
442 CALL dlacpy(
'Full', n1, n2, t( 1, n1+1 ), ldst, li, ldst )
443 CALL dlacpy(
'Full', n1, n2, s( 1, n1+1 ), ldst,
444 $ ir( n2+1, n1+1 ), ldst )
445 CALL dtgsy2(
'N', 0, n1, n2, s, ldst, s( n1+1, n1+1 ), ldst,
446 $ ir( n2+1, n1+1 ), ldst, t, ldst, t( n1+1, n1+1 ),
447 $ ldst, li, ldst, scale, dsum, dscale, iwork, idum,
461 CALL dscal( n1, -one, li( 1, i ), 1 )
462 li( n1+i, i ) = scale
464 CALL dgeqr2( m, n2, li, ldst, taul, work, linfo )
467 CALL dorg2r( m, m, n2, li, ldst, taul, work, linfo )
478 ir( n2+i, i ) = scale
480 CALL dgerq2( n1, m, ir( n2+1, 1 ), ldst, taur, work, linfo )
483 CALL dorgr2( m, m, n1, ir, ldst, taur, work, linfo )
489 CALL dgemm(
'T',
'N', m, m, m, one, li, ldst, s, ldst, zero,
491 CALL dgemm(
'N',
'T', m, m, m, one, work, m, ir, ldst, zero, s,
493 CALL dgemm(
'T',
'N', m, m, m, one, li, ldst, t, ldst, zero,
495 CALL dgemm(
'N',
'T', m, m, m, one, work, m, ir, ldst, zero, t,
497 CALL dlacpy(
'F', m, m, s, ldst, scpy, ldst )
498 CALL dlacpy(
'F', m, m, t, ldst, tcpy, ldst )
499 CALL dlacpy(
'F', m, m, ir, ldst, ircop, ldst )
500 CALL dlacpy(
'F', m, m, li, ldst, licop, ldst )
505 CALL dgerq2( m, m, t, ldst, taur, work, linfo )
508 CALL dormr2(
'R',
'T', m, m, m, t, ldst, taur, s, ldst, work,
512 CALL dormr2(
'L',
'N', m, m, m, t, ldst, taur, ir, ldst, work,
522 CALL dlassq( n1, s( n2+1, i ), 1, dscale, dsum )
524 brqa21 = dscale*sqrt( dsum )
529 CALL dgeqr2( m, m, tcpy, ldst, taul, work, linfo )
532 CALL dorm2r(
'L',
'T', m, m, m, tcpy, ldst, taul, scpy, ldst,
534 CALL dorm2r(
'R',
'N', m, m, m, tcpy, ldst, taul, licop, ldst,
544 CALL dlassq( n1, scpy( n2+1, i ), 1, dscale, dsum )
546 bqra21 = dscale*sqrt( dsum )
552 IF( bqra21.LE.brqa21 .AND. bqra21.LE.thresha )
THEN
553 CALL dlacpy(
'F', m, m, scpy, ldst, s, ldst )
554 CALL dlacpy(
'F', m, m, tcpy, ldst, t, ldst )
555 CALL dlacpy(
'F', m, m, ircop, ldst, ir, ldst )
556 CALL dlacpy(
'F', m, m, licop, ldst, li, ldst )
557 ELSE IF( brqa21.GE.thresha )
THEN
563 CALL dlaset(
'Lower', m-1, m-1, zero, zero, t(2,1), ldst )
572 CALL dlacpy(
'Full', m, m, a( j1, j1 ), lda, work( m*m+1 ),
574 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, s, ldst, zero,
576 CALL dgemm(
'N',
'N', m, m, m, -one, work, m, ir, ldst, one,
580 CALL dlassq( m*m, work( m*m+1 ), 1, dscale, dsum )
581 sa = dscale*sqrt( dsum )
583 CALL dlacpy(
'Full', m, m, b( j1, j1 ), ldb, work( m*m+1 ),
585 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, t, ldst, zero,
587 CALL dgemm(
'N',
'N', m, m, m, -one, work, m, ir, ldst, one,
591 CALL dlassq( m*m, work( m*m+1 ), 1, dscale, dsum )
592 sb = dscale*sqrt( dsum )
593 strong = sa.LE.thresha .AND. sb.LE.threshb
602 CALL dlaset(
'Full', n1, n2, zero, zero, s(n2+1,1), ldst )
606 CALL dlacpy(
'F', m, m, s, ldst, a( j1, j1 ), lda )
607 CALL dlacpy(
'F', m, m, t, ldst, b( j1, j1 ), ldb )
608 CALL dlaset(
'Full', ldst, ldst, zero, zero, t, ldst )
612 CALL dlaset(
'Full', m, m, zero, zero, work, m )
615 idum = lwork - m*m - 2
617 CALL dlagv2( a( j1, j1 ), lda, b( j1, j1 ), ldb, ar, ai, be,
618 $ work( 1 ), work( 2 ), t( 1, 1 ), t( 2, 1 ) )
619 work( m+1 ) = -work( 2 )
620 work( m+2 ) = work( 1 )
621 t( n2, n2 ) = t( 1, 1 )
622 t( 1, 2 ) = -t( 2, 1 )
628 CALL dlagv2( a( j1+n2, j1+n2 ), lda, b( j1+n2, j1+n2 ), ldb,
629 $ taur, taul, work( m*m+1 ), work( n2*m+n2+1 ),
630 $ work( n2*m+n2+2 ), t( n2+1, n2+1 ),
632 work( m*m ) = work( n2*m+n2+1 )
633 work( m*m-1 ) = -work( n2*m+n2+2 )
634 t( m, m ) = t( n2+1, n2+1 )
635 t( m-1, m ) = -t( m, m-1 )
637 CALL dgemm(
'T',
'N', n2, n1, n2, one, work, m, a( j1, j1+n2 ),
638 $ lda, zero, work( m*m+1 ), n2 )
639 CALL dlacpy(
'Full', n2, n1, work( m*m+1 ), n2, a( j1, j1+n2 ),
641 CALL dgemm(
'T',
'N', n2, n1, n2, one, work, m, b( j1, j1+n2 ),
642 $ ldb, zero, work( m*m+1 ), n2 )
643 CALL dlacpy(
'Full', n2, n1, work( m*m+1 ), n2, b( j1, j1+n2 ),
645 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, work, m, zero,
647 CALL dlacpy(
'Full', m, m, work( m*m+1 ), m, li, ldst )
648 CALL dgemm(
'N',
'N', n2, n1, n1, one, a( j1, j1+n2 ), lda,
649 $ t( n2+1, n2+1 ), ldst, zero, work, n2 )
650 CALL dlacpy(
'Full', n2, n1, work, n2, a( j1, j1+n2 ), lda )
651 CALL dgemm(
'N',
'N', n2, n1, n1, one, b( j1, j1+n2 ), ldb,
652 $ t( n2+1, n2+1 ), ldst, zero, work, n2 )
653 CALL dlacpy(
'Full', n2, n1, work, n2, b( j1, j1+n2 ), ldb )
654 CALL dgemm(
'T',
'N', m, m, m, one, ir, ldst, t, ldst, zero,
656 CALL dlacpy(
'Full', m, m, work, m, ir, ldst )
661 CALL dgemm(
'N',
'N', n, m, m, one, q( 1, j1 ), ldq, li,
662 $ ldst, zero, work, n )
663 CALL dlacpy(
'Full', n, m, work, n, q( 1, j1 ), ldq )
668 CALL dgemm(
'N',
'N', n, m, m, one, z( 1, j1 ), ldz, ir,
669 $ ldst, zero, work, n )
670 CALL dlacpy(
'Full', n, m, work, n, z( 1, j1 ), ldz )
679 CALL dgemm(
'T',
'N', m, n-i+1, m, one, li, ldst,
680 $ a( j1, i ), lda, zero, work, m )
681 CALL dlacpy(
'Full', m, n-i+1, work, m, a( j1, i ), lda )
682 CALL dgemm(
'T',
'N', m, n-i+1, m, one, li, ldst,
683 $ b( j1, i ), ldb, zero, work, m )
684 CALL dlacpy(
'Full', m, n-i+1, work, m, b( j1, i ), ldb )
688 CALL dgemm(
'N',
'N', i, m, m, one, a( 1, j1 ), lda, ir,
689 $ ldst, zero, work, i )
690 CALL dlacpy(
'Full', i, m, work, i, a( 1, j1 ), lda )
691 CALL dgemm(
'N',
'N', i, m, m, one, b( 1, j1 ), ldb, ir,
692 $ ldst, zero, work, i )
693 CALL dlacpy(
'Full', i, m, work, i, b( 1, j1 ), ldb )
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dgeqr2(m, n, a, lda, tau, work, info)
DGEQR2 computes the QR factorization of a general rectangular matrix using an unblocked algorithm.
subroutine dgerq2(m, n, a, lda, tau, work, info)
DGERQ2 computes the RQ factorization of a general rectangular matrix using an unblocked algorithm.
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlagv2(a, lda, b, ldb, alphar, alphai, beta, csl, snl, csr, snr)
DLAGV2 computes the Generalized Schur factorization of a real 2-by-2 matrix pencil (A,...
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dlassq(n, x, incx, scale, sumsq)
DLASSQ updates a sum of squares represented in scaled form.
subroutine drot(n, dx, incx, dy, incy, c, s)
DROT
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine dtgex2(wantq, wantz, n, a, lda, b, ldb, q, ldq, z, ldz, j1, n1, n2, work, lwork, info)
DTGEX2 swaps adjacent diagonal blocks in an upper (quasi) triangular matrix pair by an orthogonal equ...
subroutine dtgsy2(trans, ijob, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, scale, rdsum, rdscal, iwork, pq, info)
DTGSY2 solves the generalized Sylvester equation (unblocked algorithm).
subroutine dorg2r(m, n, k, a, lda, tau, work, info)
DORG2R generates all or part of the orthogonal matrix Q from a QR factorization determined by sgeqrf ...
subroutine dorgr2(m, n, k, a, lda, tau, work, info)
DORGR2 generates all or part of the orthogonal matrix Q from an RQ factorization determined by sgerqf...
subroutine dorm2r(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
DORM2R multiplies a general matrix by the orthogonal matrix from a QR factorization determined by sge...
subroutine dormr2(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
DORMR2 multiplies a general matrix by the orthogonal matrix from a RQ factorization determined by sge...