217 SUBROUTINE dtgex2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
218 $ LDZ, J1, N1, N2, WORK, LWORK, INFO )
226 INTEGER INFO, J1, LDA, LDB, LDQ, LDZ, LWORK, N, N1, N2
229 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
230 $ work( * ), z( ldz, * )
238 DOUBLE PRECISION ZERO, ONE
239 parameter( zero = 0.0d+0, one = 1.0d+0 )
240 DOUBLE PRECISION TWENTY
241 parameter( twenty = 2.0d+01 )
243 parameter( ldst = 4 )
245 parameter( wands = .true. )
249 INTEGER I, IDUM, LINFO, M
250 DOUBLE PRECISION BQRA21, BRQA21, DDUM, DNORMA, DNORMB, DSCALE,
251 $ dsum, eps, f, g, sa, sb, scale, smlnum,
255 INTEGER IWORK( LDST + 2 )
256 DOUBLE PRECISION AI( 2 ), AR( 2 ), BE( 2 ), IR( LDST, LDST ),
257 $ ircop( ldst, ldst ), li( ldst, ldst ),
258 $ licop( ldst, ldst ), s( ldst, ldst ),
259 $ scpy( ldst, ldst ), t( ldst, ldst ),
260 $ taul( ldst ), taur( ldst ), tcpy( ldst, ldst )
263 DOUBLE PRECISION DLAMCH
273 INTRINSIC abs, max, sqrt
281 IF( n.LE.1 .OR. n1.LE.0 .OR. n2.LE.0 )
283 IF( n1.GT.n .OR. ( j1+n1 ).GT.n )
286 IF( lwork.LT.max( 1, n*m, m*m*2 ) )
THEN
288 work( 1 ) = max( 1, n*m, m*m*2 )
297 CALL dlaset(
'Full', ldst, ldst, zero, zero, li, ldst )
298 CALL dlaset(
'Full', ldst, ldst, zero, zero, ir, ldst )
299 CALL dlacpy(
'Full', m, m, a( j1, j1 ), lda, s, ldst )
300 CALL dlacpy(
'Full', m, m, b( j1, j1 ), ldb, t, ldst )
305 smlnum = dlamch(
'S' ) / eps
308 CALL dlacpy(
'Full', m, m, s, ldst, work, m )
309 CALL dlassq( m*m, work, 1, dscale, dsum )
310 dnorma = dscale*sqrt( dsum )
313 CALL dlacpy(
'Full', m, m, t, ldst, work, m )
314 CALL dlassq( m*m, work, 1, dscale, dsum )
315 dnormb = dscale*sqrt( dsum )
325 thresha = max( twenty*eps*dnorma, smlnum )
326 threshb = max( twenty*eps*dnormb, smlnum )
335 f = s( 2, 2 )*t( 1, 1 ) - t( 2, 2 )*s( 1, 1 )
336 g = s( 2, 2 )*t( 1, 2 ) - t( 2, 2 )*s( 1, 2 )
337 sa = abs( s( 2, 2 ) ) * abs( t( 1, 1 ) )
338 sb = abs( s( 1, 1 ) ) * abs( t( 2, 2 ) )
339 CALL dlartg( f, g, ir( 1, 2 ), ir( 1, 1 ), ddum )
340 ir( 2, 1 ) = -ir( 1, 2 )
341 ir( 2, 2 ) = ir( 1, 1 )
342 CALL drot( 2, s( 1, 1 ), 1, s( 1, 2 ), 1, ir( 1, 1 ),
344 CALL drot( 2, t( 1, 1 ), 1, t( 1, 2 ), 1, ir( 1, 1 ),
347 CALL dlartg( s( 1, 1 ), s( 2, 1 ), li( 1, 1 ), li( 2,
351 CALL dlartg( t( 1, 1 ), t( 2, 1 ), li( 1, 1 ), li( 2,
355 CALL drot( 2, s( 1, 1 ), ldst, s( 2, 1 ), ldst, li( 1, 1 ),
357 CALL drot( 2, t( 1, 1 ), ldst, t( 2, 1 ), ldst, li( 1, 1 ),
359 li( 2, 2 ) = li( 1, 1 )
360 li( 1, 2 ) = -li( 2, 1 )
365 weak = abs( s( 2, 1 ) ) .LE. thresha .AND.
366 $ abs( t( 2, 1 ) ) .LE. threshb
377 CALL dlacpy(
'Full', m, m, a( j1, j1 ), lda,
380 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, s, ldst,
383 CALL dgemm(
'N',
'T', m, m, m, -one, work, m, ir, ldst,
388 CALL dlassq( m*m, work( m*m+1 ), 1, dscale, dsum )
389 sa = dscale*sqrt( dsum )
391 CALL dlacpy(
'Full', m, m, b( j1, j1 ), ldb,
394 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, t, ldst,
397 CALL dgemm(
'N',
'T', m, m, m, -one, work, m, ir, ldst,
402 CALL dlassq( m*m, work( m*m+1 ), 1, dscale, dsum )
403 sb = dscale*sqrt( dsum )
404 strong = sa.LE.thresha .AND. sb.LE.threshb
412 CALL drot( j1+1, a( 1, j1 ), 1, a( 1, j1+1 ), 1, ir( 1, 1 ),
414 CALL drot( j1+1, b( 1, j1 ), 1, b( 1, j1+1 ), 1, ir( 1, 1 ),
416 CALL drot( n-j1+1, a( j1, j1 ), lda, a( j1+1, j1 ), lda,
417 $ li( 1, 1 ), li( 2, 1 ) )
418 CALL drot( n-j1+1, b( j1, j1 ), ldb, b( j1+1, j1 ), ldb,
419 $ li( 1, 1 ), li( 2, 1 ) )
429 $
CALL drot( n, z( 1, j1 ), 1, z( 1, j1+1 ), 1, ir( 1, 1 ),
432 $
CALL drot( n, q( 1, j1 ), 1, q( 1, j1+1 ), 1, li( 1, 1 ),
449 CALL dlacpy(
'Full', n1, n2, t( 1, n1+1 ), ldst, li, ldst )
450 CALL dlacpy(
'Full', n1, n2, s( 1, n1+1 ), ldst,
451 $ ir( n2+1, n1+1 ), ldst )
452 CALL dtgsy2(
'N', 0, n1, n2, s, ldst, s( n1+1, n1+1 ), ldst,
453 $ ir( n2+1, n1+1 ), ldst, t, ldst, t( n1+1, n1+1 ),
454 $ ldst, li, ldst, scale, dsum, dscale, iwork, idum,
468 CALL dscal( n1, -one, li( 1, i ), 1 )
469 li( n1+i, i ) = scale
471 CALL dgeqr2( m, n2, li, ldst, taul, work, linfo )
474 CALL dorg2r( m, m, n2, li, ldst, taul, work, linfo )
485 ir( n2+i, i ) = scale
487 CALL dgerq2( n1, m, ir( n2+1, 1 ), ldst, taur, work, linfo )
490 CALL dorgr2( m, m, n1, ir, ldst, taur, work, linfo )
496 CALL dgemm(
'T',
'N', m, m, m, one, li, ldst, s, ldst, zero,
498 CALL dgemm(
'N',
'T', m, m, m, one, work, m, ir, ldst, zero,
501 CALL dgemm(
'T',
'N', m, m, m, one, li, ldst, t, ldst, zero,
503 CALL dgemm(
'N',
'T', m, m, m, one, work, m, ir, ldst, zero,
506 CALL dlacpy(
'F', m, m, s, ldst, scpy, ldst )
507 CALL dlacpy(
'F', m, m, t, ldst, tcpy, ldst )
508 CALL dlacpy(
'F', m, m, ir, ldst, ircop, ldst )
509 CALL dlacpy(
'F', m, m, li, ldst, licop, ldst )
514 CALL dgerq2( m, m, t, ldst, taur, work, linfo )
517 CALL dormr2(
'R',
'T', m, m, m, t, ldst, taur, s, ldst,
522 CALL dormr2(
'L',
'N', m, m, m, t, ldst, taur, ir, ldst,
533 CALL dlassq( n1, s( n2+1, i ), 1, dscale, dsum )
535 brqa21 = dscale*sqrt( dsum )
540 CALL dgeqr2( m, m, tcpy, ldst, taul, work, linfo )
543 CALL dorm2r(
'L',
'T', m, m, m, tcpy, ldst, taul, scpy,
546 CALL dorm2r(
'R',
'N', m, m, m, tcpy, ldst, taul, licop,
557 CALL dlassq( n1, scpy( n2+1, i ), 1, dscale, dsum )
559 bqra21 = dscale*sqrt( dsum )
565 IF( bqra21.LE.brqa21 .AND. bqra21.LE.thresha )
THEN
566 CALL dlacpy(
'F', m, m, scpy, ldst, s, ldst )
567 CALL dlacpy(
'F', m, m, tcpy, ldst, t, ldst )
568 CALL dlacpy(
'F', m, m, ircop, ldst, ir, ldst )
569 CALL dlacpy(
'F', m, m, licop, ldst, li, ldst )
570 ELSE IF( brqa21.GE.thresha )
THEN
576 CALL dlaset(
'Lower', m-1, m-1, zero, zero, t(2,1), ldst )
585 CALL dlacpy(
'Full', m, m, a( j1, j1 ), lda,
588 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, s, ldst,
591 CALL dgemm(
'N',
'N', m, m, m, -one, work, m, ir, ldst,
596 CALL dlassq( m*m, work( m*m+1 ), 1, dscale, dsum )
597 sa = dscale*sqrt( dsum )
599 CALL dlacpy(
'Full', m, m, b( j1, j1 ), ldb,
602 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, t, ldst,
605 CALL dgemm(
'N',
'N', m, m, m, -one, work, m, ir, ldst,
610 CALL dlassq( m*m, work( m*m+1 ), 1, dscale, dsum )
611 sb = dscale*sqrt( dsum )
612 strong = sa.LE.thresha .AND. sb.LE.threshb
621 CALL dlaset(
'Full', n1, n2, zero, zero, s(n2+1,1), ldst )
625 CALL dlacpy(
'F', m, m, s, ldst, a( j1, j1 ), lda )
626 CALL dlacpy(
'F', m, m, t, ldst, b( j1, j1 ), ldb )
627 CALL dlaset(
'Full', ldst, ldst, zero, zero, t, ldst )
631 CALL dlaset(
'Full', m, m, zero, zero, work, m )
634 idum = lwork - m*m - 2
636 CALL dlagv2( a( j1, j1 ), lda, b( j1, j1 ), ldb, ar, ai,
638 $ work( 1 ), work( 2 ), t( 1, 1 ), t( 2, 1 ) )
639 work( m+1 ) = -work( 2 )
640 work( m+2 ) = work( 1 )
641 t( n2, n2 ) = t( 1, 1 )
642 t( 1, 2 ) = -t( 2, 1 )
648 CALL dlagv2( a( j1+n2, j1+n2 ), lda, b( j1+n2, j1+n2 ),
650 $ taur, taul, work( m*m+1 ), work( n2*m+n2+1 ),
651 $ work( n2*m+n2+2 ), t( n2+1, n2+1 ),
653 work( m*m ) = work( n2*m+n2+1 )
654 work( m*m-1 ) = -work( n2*m+n2+2 )
655 t( m, m ) = t( n2+1, n2+1 )
656 t( m-1, m ) = -t( m, m-1 )
658 CALL dgemm(
'T',
'N', n2, n1, n2, one, work, m, a( j1,
660 $ lda, zero, work( m*m+1 ), n2 )
661 CALL dlacpy(
'Full', n2, n1, work( m*m+1 ), n2, a( j1,
664 CALL dgemm(
'T',
'N', n2, n1, n2, one, work, m, b( j1,
666 $ ldb, zero, work( m*m+1 ), n2 )
667 CALL dlacpy(
'Full', n2, n1, work( m*m+1 ), n2, b( j1,
670 CALL dgemm(
'N',
'N', m, m, m, one, li, ldst, work, m, zero,
672 CALL dlacpy(
'Full', m, m, work( m*m+1 ), m, li, ldst )
673 CALL dgemm(
'N',
'N', n2, n1, n1, one, a( j1, j1+n2 ), lda,
674 $ t( n2+1, n2+1 ), ldst, zero, work, n2 )
675 CALL dlacpy(
'Full', n2, n1, work, n2, a( j1, j1+n2 ), lda )
676 CALL dgemm(
'N',
'N', n2, n1, n1, one, b( j1, j1+n2 ), ldb,
677 $ t( n2+1, n2+1 ), ldst, zero, work, n2 )
678 CALL dlacpy(
'Full', n2, n1, work, n2, b( j1, j1+n2 ), ldb )
679 CALL dgemm(
'T',
'N', m, m, m, one, ir, ldst, t, ldst, zero,
681 CALL dlacpy(
'Full', m, m, work, m, ir, ldst )
686 CALL dgemm(
'N',
'N', n, m, m, one, q( 1, j1 ), ldq, li,
687 $ ldst, zero, work, n )
688 CALL dlacpy(
'Full', n, m, work, n, q( 1, j1 ), ldq )
693 CALL dgemm(
'N',
'N', n, m, m, one, z( 1, j1 ), ldz, ir,
694 $ ldst, zero, work, n )
695 CALL dlacpy(
'Full', n, m, work, n, z( 1, j1 ), ldz )
704 CALL dgemm(
'T',
'N', m, n-i+1, m, one, li, ldst,
705 $ a( j1, i ), lda, zero, work, m )
706 CALL dlacpy(
'Full', m, n-i+1, work, m, a( j1, i ), lda )
707 CALL dgemm(
'T',
'N', m, n-i+1, m, one, li, ldst,
708 $ b( j1, i ), ldb, zero, work, m )
709 CALL dlacpy(
'Full', m, n-i+1, work, m, b( j1, i ), ldb )
713 CALL dgemm(
'N',
'N', i, m, m, one, a( 1, j1 ), lda, ir,
714 $ ldst, zero, work, i )
715 CALL dlacpy(
'Full', i, m, work, i, a( 1, j1 ), lda )
716 CALL dgemm(
'N',
'N', i, m, m, one, b( 1, j1 ), ldb, ir,
717 $ ldst, zero, work, i )
718 CALL dlacpy(
'Full', i, m, work, i, b( 1, j1 ), ldb )