226 SUBROUTINE sgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB,
228 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
237 CHARACTER COMPQ, COMPZ
238 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
241 REAL A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
242 $ Z( LDZ, * ), WORK( * )
249 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
252 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
253 CHARACTER*1 COMPQ2, COMPZ2
254 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
255 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
256 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
257 REAL C, C1, C2, S, S1, S2, TEMP, TEMP1, TEMP2, TEMP3
263 EXTERNAL ilaenv, lsame, sroundup_lwork
278 nb = ilaenv( 1,
'SGGHD3',
' ', n, ilo, ihi, -1 )
285 work( 1 ) = sroundup_lwork( lwkopt )
286 initq = lsame( compq,
'I' )
287 wantq = initq .OR. lsame( compq,
'V' )
288 initz = lsame( compz,
'I' )
289 wantz = initz .OR. lsame( compz,
'V' )
290 lquery = ( lwork.EQ.-1 )
292 IF( .NOT.lsame( compq,
'N' ) .AND. .NOT.wantq )
THEN
294 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
296 ELSE IF( n.LT.0 )
THEN
298 ELSE IF( ilo.LT.1 )
THEN
300 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
302 ELSE IF( lda.LT.max( 1, n ) )
THEN
304 ELSE IF( ldb.LT.max( 1, n ) )
THEN
306 ELSE IF( ( wantq .AND. ldq.LT.n ) .OR. ldq.LT.1 )
THEN
308 ELSE IF( ( wantz .AND. ldz.LT.n ) .OR. ldz.LT.1 )
THEN
310 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN
314 CALL xerbla(
'SGGHD3', -info )
316 ELSE IF( lquery )
THEN
323 $
CALL slaset(
'All', n, n, zero, one, q, ldq )
325 $
CALL slaset(
'All', n, n, zero, one, z, ldz )
330 $
CALL slaset(
'Lower', n-1, n-1, zero, zero, b(2, 1), ldb )
341 nbmin = ilaenv( 2,
'SGGHD3',
' ', n, ilo, ihi, -1 )
342 IF( nb.GT.1 .AND. nb.LT.nh )
THEN
346 nx = max( nb, ilaenv( 3,
'SGGHD3',
' ', n, ilo, ihi, -1 ) )
351 IF( lwork.LT.lwkopt )
THEN
357 nbmin = max( 2, ilaenv( 2,
'SGGHD3',
' ', n, ilo, ihi,
359 IF( lwork.GE.6*n*nbmin )
THEN
368 IF( nb.LT.nbmin .OR. nb.GE.nh )
THEN
378 kacc22 = ilaenv( 16,
'SGGHD3',
' ', n, ilo, ihi, -1 )
380 DO jcol = ilo, ihi-2, nb
381 nnb = min( nb, ihi-jcol-1 )
389 n2nb = ( ihi-jcol-1 ) / nnb - 1
390 nblst = ihi - jcol - n2nb*nnb
391 CALL slaset(
'All', nblst, nblst, zero, one, work,
393 pw = nblst * nblst + 1
395 CALL slaset(
'All', 2*nnb, 2*nnb, zero, one,
396 $ work( pw ), 2*nnb )
402 DO j = jcol, jcol+nnb-1
409 CALL slartg( temp, a( i, j ), c, s, a( i-1, j ) )
416 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
418 jrow = j + n2nb*nnb + 2
422 DO jj = ppw, ppw+len-1
423 temp = work( jj + nblst )
424 work( jj + nblst ) = c*temp - s*work( jj )
425 work( jj ) = s*temp + c*work( jj )
428 ppw = ppw - nblst - 1
431 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
433 DO jrow = j0, j+2, -nnb
436 DO i = jrow+nnb-1, jrow, -1
439 DO jj = ppw, ppw+len-1
440 temp = work( jj + 2*nnb )
441 work( jj + 2*nnb ) = c*temp - s*work( jj )
442 work( jj ) = s*temp + c*work( jj )
445 ppw = ppw - 2*nnb - 1
447 ppwo = ppwo + 4*nnb*nnb
466 DO i = min( jj+1, ihi ), j+2, -1
470 b( i, jj ) = c*temp - s*b( i-1, jj )
471 b( i-1, jj ) = s*temp + c*b( i-1, jj )
477 temp = b( jj+1, jj+1 )
478 CALL slartg( temp, b( jj+1, jj ), c, s,
481 CALL srot( jj-top, b( top+1, jj+1 ), 1,
482 $ b( top+1, jj ), 1, c, s )
495 jj = mod( ihi-j-1, 3 )
496 DO i = ihi-j-3, jj+1, -3
506 temp1 = a( k, j+i+1 )
507 temp2 = a( k, j+i+2 )
508 temp3 = a( k, j+i+3 )
509 a( k, j+i+3 ) = c2*temp3 + s2*temp2
510 temp2 = -s2*temp3 + c2*temp2
511 a( k, j+i+2 ) = c1*temp2 + s1*temp1
512 temp1 = -s1*temp2 + c1*temp1
513 a( k, j+i+1 ) = c*temp1 + s*temp
514 a( k, j+i ) = -s*temp1 + c*temp
520 CALL srot( ihi-top, a( top+1, j+i+1 ), 1,
521 $ a( top+1, j+i ), 1, a( j+1+i, j ),
528 IF ( j .LT. jcol + nnb - 1 )
THEN
541 jrow = ihi - nblst + 1
542 CALL sgemv(
'Transpose', nblst, len, one, work,
543 $ nblst, a( jrow, j+1 ), 1, zero,
546 DO i = jrow, jrow+nblst-len-1
547 work( ppw ) = a( i, j+1 )
550 CALL strmv(
'Lower',
'Transpose',
'Non-unit',
551 $ nblst-len, work( len*nblst + 1 ), nblst,
552 $ work( pw+len ), 1 )
553 CALL sgemv(
'Transpose', len, nblst-len, one,
554 $ work( (len+1)*nblst - len + 1 ), nblst,
555 $ a( jrow+nblst-len, j+1 ), 1, one,
556 $ work( pw+len ), 1 )
558 DO i = jrow, jrow+nblst-1
559 a( i, j+1 ) = work( ppw )
576 ppwo = 1 + nblst*nblst
578 DO jrow = j0, jcol+1, -nnb
580 DO i = jrow, jrow+nnb-1
581 work( ppw ) = a( i, j+1 )
585 DO i = jrow+nnb, jrow+nnb+len-1
586 work( ppw ) = a( i, j+1 )
589 CALL strmv(
'Upper',
'Transpose',
'Non-unit',
591 $ work( ppwo + nnb ), 2*nnb, work( pw ),
593 CALL strmv(
'Lower',
'Transpose',
'Non-unit',
595 $ work( ppwo + 2*len*nnb ),
596 $ 2*nnb, work( pw + len ), 1 )
597 CALL sgemv(
'Transpose', nnb, len, one,
598 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
599 $ one, work( pw ), 1 )
600 CALL sgemv(
'Transpose', len, nnb, one,
601 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
602 $ a( jrow+nnb, j+1 ), 1, one,
603 $ work( pw+len ), 1 )
605 DO i = jrow, jrow+len+nnb-1
606 a( i, j+1 ) = work( ppw )
609 ppwo = ppwo + 4*nnb*nnb
616 cola = n - jcol - nnb + 1
618 CALL sgemm(
'Transpose',
'No Transpose', nblst,
619 $ cola, nblst, one, work, nblst,
620 $ a( j, jcol+nnb ), lda, zero, work( pw ),
622 CALL slacpy(
'All', nblst, cola, work( pw ), nblst,
623 $ a( j, jcol+nnb ), lda )
624 ppwo = nblst*nblst + 1
626 DO j = j0, jcol+1, -nnb
638 CALL sorm22(
'Left',
'Transpose', 2*nnb, cola, nnb,
639 $ nnb, work( ppwo ), 2*nnb,
640 $ a( j, jcol+nnb ), lda, work( pw ),
646 CALL sgemm(
'Transpose',
'No Transpose', 2*nnb,
647 $ cola, 2*nnb, one, work( ppwo ), 2*nnb,
648 $ a( j, jcol+nnb ), lda, zero, work( pw ),
650 CALL slacpy(
'All', 2*nnb, cola, work( pw ), 2*nnb,
651 $ a( j, jcol+nnb ), lda )
653 ppwo = ppwo + 4*nnb*nnb
661 topq = max( 2, j - jcol + 1 )
667 CALL sgemm(
'No Transpose',
'No Transpose', nh,
668 $ nblst, nblst, one, q( topq, j ), ldq,
669 $ work, nblst, zero, work( pw ), nh )
670 CALL slacpy(
'All', nh, nblst, work( pw ), nh,
671 $ q( topq, j ), ldq )
672 ppwo = nblst*nblst + 1
674 DO j = j0, jcol+1, -nnb
676 topq = max( 2, j - jcol + 1 )
683 CALL sorm22(
'Right',
'No Transpose', nh, 2*nnb,
684 $ nnb, nnb, work( ppwo ), 2*nnb,
685 $ q( topq, j ), ldq, work( pw ),
691 CALL sgemm(
'No Transpose',
'No Transpose', nh,
692 $ 2*nnb, 2*nnb, one, q( topq, j ), ldq,
693 $ work( ppwo ), 2*nnb, zero, work( pw ),
695 CALL slacpy(
'All', nh, 2*nnb, work( pw ), nh,
696 $ q( topq, j ), ldq )
698 ppwo = ppwo + 4*nnb*nnb
704 IF ( wantz .OR. top.GT.0 )
THEN
709 CALL slaset(
'All', nblst, nblst, zero, one, work,
711 pw = nblst * nblst + 1
713 CALL slaset(
'All', 2*nnb, 2*nnb, zero, one,
714 $ work( pw ), 2*nnb )
720 DO j = jcol, jcol+nnb-1
721 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
723 jrow = j + n2nb*nnb + 2
729 DO jj = ppw, ppw+len-1
730 temp = work( jj + nblst )
731 work( jj + nblst ) = c*temp - s*work( jj )
732 work( jj ) = s*temp + c*work( jj )
735 ppw = ppw - nblst - 1
738 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
740 DO jrow = j0, j+2, -nnb
743 DO i = jrow+nnb-1, jrow, -1
748 DO jj = ppw, ppw+len-1
749 temp = work( jj + 2*nnb )
750 work( jj + 2*nnb ) = c*temp - s*work( jj )
751 work( jj ) = s*temp + c*work( jj )
754 ppw = ppw - 2*nnb - 1
756 ppwo = ppwo + 4*nnb*nnb
761 CALL slaset(
'Lower', ihi - jcol - 1, nnb, zero, zero,
762 $ a( jcol + 2, jcol ), lda )
763 CALL slaset(
'Lower', ihi - jcol - 1, nnb, zero, zero,
764 $ b( jcol + 2, jcol ), ldb )
771 CALL sgemm(
'No Transpose',
'No Transpose', top,
772 $ nblst, nblst, one, a( 1, j ), lda,
773 $ work, nblst, zero, work( pw ), top )
774 CALL slacpy(
'All', top, nblst, work( pw ), top,
776 ppwo = nblst*nblst + 1
778 DO j = j0, jcol+1, -nnb
783 CALL sorm22(
'Right',
'No Transpose', top,
785 $ nnb, nnb, work( ppwo ), 2*nnb,
786 $ a( 1, j ), lda, work( pw ),
792 CALL sgemm(
'No Transpose',
'No Transpose', top,
793 $ 2*nnb, 2*nnb, one, a( 1, j ), lda,
794 $ work( ppwo ), 2*nnb, zero,
796 CALL slacpy(
'All', top, 2*nnb, work( pw ), top,
799 ppwo = ppwo + 4*nnb*nnb
803 CALL sgemm(
'No Transpose',
'No Transpose', top,
804 $ nblst, nblst, one, b( 1, j ), ldb,
805 $ work, nblst, zero, work( pw ), top )
806 CALL slacpy(
'All', top, nblst, work( pw ), top,
808 ppwo = nblst*nblst + 1
810 DO j = j0, jcol+1, -nnb
815 CALL sorm22(
'Right',
'No Transpose', top,
817 $ nnb, nnb, work( ppwo ), 2*nnb,
818 $ b( 1, j ), ldb, work( pw ),
824 CALL sgemm(
'No Transpose',
'No Transpose', top,
825 $ 2*nnb, 2*nnb, one, b( 1, j ), ldb,
826 $ work( ppwo ), 2*nnb, zero,
828 CALL slacpy(
'All', top, 2*nnb, work( pw ), top,
831 ppwo = ppwo + 4*nnb*nnb
840 topq = max( 2, j - jcol + 1 )
846 CALL sgemm(
'No Transpose',
'No Transpose', nh,
847 $ nblst, nblst, one, z( topq, j ), ldz,
848 $ work, nblst, zero, work( pw ), nh )
849 CALL slacpy(
'All', nh, nblst, work( pw ), nh,
850 $ z( topq, j ), ldz )
851 ppwo = nblst*nblst + 1
853 DO j = j0, jcol+1, -nnb
855 topq = max( 2, j - jcol + 1 )
862 CALL sorm22(
'Right',
'No Transpose', nh, 2*nnb,
863 $ nnb, nnb, work( ppwo ), 2*nnb,
864 $ z( topq, j ), ldz, work( pw ),
870 CALL sgemm(
'No Transpose',
'No Transpose', nh,
871 $ 2*nnb, 2*nnb, one, z( topq, j ), ldz,
872 $ work( ppwo ), 2*nnb, zero, work( pw ),
874 CALL slacpy(
'All', nh, 2*nnb, work( pw ), nh,
875 $ z( topq, j ), ldz )
877 ppwo = ppwo + 4*nnb*nnb
888 IF ( jcol.NE.ilo )
THEN
896 $
CALL sgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb,
898 $ ldq, z, ldz, ierr )
900 work( 1 ) = sroundup_lwork( lwkopt )