228 SUBROUTINE sgghd3( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,
229 $ LDQ, Z, LDZ, WORK, LWORK, INFO )
238 CHARACTER COMPQ, COMPZ
239 INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N, LWORK
242 REAL A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
243 $ z( ldz, * ), work( * )
250 parameter( zero = 0.0e+0, one = 1.0e+0 )
253 LOGICAL BLK22, INITQ, INITZ, LQUERY, WANTQ, WANTZ
254 CHARACTER*1 COMPQ2, COMPZ2
255 INTEGER COLA, I, IERR, J, J0, JCOL, JJ, JROW, K,
256 $ kacc22, len, lwkopt, n2nb, nb, nblst, nbmin,
257 $ nh, nnb, nx, ppw, ppwo, pw, top, topq
258 REAL C, C1, C2, S, S1, S2, TEMP, TEMP1, TEMP2, TEMP3
264 EXTERNAL ilaenv, lsame, sroundup_lwork
278 nb = ilaenv( 1,
'SGGHD3',
' ', n, ilo, ihi, -1 )
279 lwkopt = max( 6*n*nb, 1 )
280 work( 1 ) = sroundup_lwork( lwkopt )
281 initq = lsame( compq,
'I' )
282 wantq = initq .OR. lsame( compq,
'V' )
283 initz = lsame( compz,
'I' )
284 wantz = initz .OR. lsame( compz,
'V' )
285 lquery = ( lwork.EQ.-1 )
287 IF( .NOT.lsame( compq,
'N' ) .AND. .NOT.wantq )
THEN
289 ELSE IF( .NOT.lsame( compz,
'N' ) .AND. .NOT.wantz )
THEN
291 ELSE IF( n.LT.0 )
THEN
293 ELSE IF( ilo.LT.1 )
THEN
295 ELSE IF( ihi.GT.n .OR. ihi.LT.ilo-1 )
THEN
297 ELSE IF( lda.LT.max( 1, n ) )
THEN
299 ELSE IF( ldb.LT.max( 1, n ) )
THEN
301 ELSE IF( ( wantq .AND. ldq.LT.n ) .OR. ldq.LT.1 )
THEN
303 ELSE IF( ( wantz .AND. ldz.LT.n ) .OR. ldz.LT.1 )
THEN
305 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN
309 CALL xerbla(
'SGGHD3', -info )
311 ELSE IF( lquery )
THEN
318 $
CALL slaset(
'All', n, n, zero, one, q, ldq )
320 $
CALL slaset(
'All', n, n, zero, one, z, ldz )
325 $
CALL slaset(
'Lower', n-1, n-1, zero, zero, b(2, 1), ldb )
337 nbmin = ilaenv( 2,
'SGGHD3',
' ', n, ilo, ihi, -1 )
338 IF( nb.GT.1 .AND. nb.LT.nh )
THEN
342 nx = max( nb, ilaenv( 3,
'SGGHD3',
' ', n, ilo, ihi, -1 ) )
347 IF( lwork.LT.lwkopt )
THEN
353 nbmin = max( 2, ilaenv( 2,
'SGGHD3',
' ', n, ilo, ihi,
355 IF( lwork.GE.6*n*nbmin )
THEN
364 IF( nb.LT.nbmin .OR. nb.GE.nh )
THEN
374 kacc22 = ilaenv( 16,
'SGGHD3',
' ', n, ilo, ihi, -1 )
376 DO jcol = ilo, ihi-2, nb
377 nnb = min( nb, ihi-jcol-1 )
385 n2nb = ( ihi-jcol-1 ) / nnb - 1
386 nblst = ihi - jcol - n2nb*nnb
387 CALL slaset(
'All', nblst, nblst, zero, one, work, nblst )
388 pw = nblst * nblst + 1
390 CALL slaset(
'All', 2*nnb, 2*nnb, zero, one,
391 $ work( pw ), 2*nnb )
397 DO j = jcol, jcol+nnb-1
404 CALL slartg( temp, a( i, j ), c, s, a( i-1, j ) )
411 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
413 jrow = j + n2nb*nnb + 2
417 DO jj = ppw, ppw+len-1
418 temp = work( jj + nblst )
419 work( jj + nblst ) = c*temp - s*work( jj )
420 work( jj ) = s*temp + c*work( jj )
423 ppw = ppw - nblst - 1
426 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
428 DO jrow = j0, j+2, -nnb
431 DO i = jrow+nnb-1, jrow, -1
434 DO jj = ppw, ppw+len-1
435 temp = work( jj + 2*nnb )
436 work( jj + 2*nnb ) = c*temp - s*work( jj )
437 work( jj ) = s*temp + c*work( jj )
440 ppw = ppw - 2*nnb - 1
442 ppwo = ppwo + 4*nnb*nnb
461 DO i = min( jj+1, ihi ), j+2, -1
465 b( i, jj ) = c*temp - s*b( i-1, jj )
466 b( i-1, jj ) = s*temp + c*b( i-1, jj )
472 temp = b( jj+1, jj+1 )
473 CALL slartg( temp, b( jj+1, jj ), c, s,
476 CALL srot( jj-top, b( top+1, jj+1 ), 1,
477 $ b( top+1, jj ), 1, c, s )
490 jj = mod( ihi-j-1, 3 )
491 DO i = ihi-j-3, jj+1, -3
501 temp1 = a( k, j+i+1 )
502 temp2 = a( k, j+i+2 )
503 temp3 = a( k, j+i+3 )
504 a( k, j+i+3 ) = c2*temp3 + s2*temp2
505 temp2 = -s2*temp3 + c2*temp2
506 a( k, j+i+2 ) = c1*temp2 + s1*temp1
507 temp1 = -s1*temp2 + c1*temp1
508 a( k, j+i+1 ) = c*temp1 + s*temp
509 a( k, j+i ) = -s*temp1 + c*temp
515 CALL srot( ihi-top, a( top+1, j+i+1 ), 1,
516 $ a( top+1, j+i ), 1, a( j+1+i, j ),
523 IF ( j .LT. jcol + nnb - 1 )
THEN
536 jrow = ihi - nblst + 1
537 CALL sgemv(
'Transpose', nblst, len, one, work,
538 $ nblst, a( jrow, j+1 ), 1, zero,
541 DO i = jrow, jrow+nblst-len-1
542 work( ppw ) = a( i, j+1 )
545 CALL strmv(
'Lower',
'Transpose',
'Non-unit',
546 $ nblst-len, work( len*nblst + 1 ), nblst,
547 $ work( pw+len ), 1 )
548 CALL sgemv(
'Transpose', len, nblst-len, one,
549 $ work( (len+1)*nblst - len + 1 ), nblst,
550 $ a( jrow+nblst-len, j+1 ), 1, one,
551 $ work( pw+len ), 1 )
553 DO i = jrow, jrow+nblst-1
554 a( i, j+1 ) = work( ppw )
571 ppwo = 1 + nblst*nblst
573 DO jrow = j0, jcol+1, -nnb
575 DO i = jrow, jrow+nnb-1
576 work( ppw ) = a( i, j+1 )
580 DO i = jrow+nnb, jrow+nnb+len-1
581 work( ppw ) = a( i, j+1 )
584 CALL strmv(
'Upper',
'Transpose',
'Non-unit', len,
585 $ work( ppwo + nnb ), 2*nnb, work( pw ),
587 CALL strmv(
'Lower',
'Transpose',
'Non-unit', nnb,
588 $ work( ppwo + 2*len*nnb ),
589 $ 2*nnb, work( pw + len ), 1 )
590 CALL sgemv(
'Transpose', nnb, len, one,
591 $ work( ppwo ), 2*nnb, a( jrow, j+1 ), 1,
592 $ one, work( pw ), 1 )
593 CALL sgemv(
'Transpose', len, nnb, one,
594 $ work( ppwo + 2*len*nnb + nnb ), 2*nnb,
595 $ a( jrow+nnb, j+1 ), 1, one,
596 $ work( pw+len ), 1 )
598 DO i = jrow, jrow+len+nnb-1
599 a( i, j+1 ) = work( ppw )
602 ppwo = ppwo + 4*nnb*nnb
609 cola = n - jcol - nnb + 1
611 CALL sgemm(
'Transpose',
'No Transpose', nblst,
612 $ cola, nblst, one, work, nblst,
613 $ a( j, jcol+nnb ), lda, zero, work( pw ),
615 CALL slacpy(
'All', nblst, cola, work( pw ), nblst,
616 $ a( j, jcol+nnb ), lda )
617 ppwo = nblst*nblst + 1
619 DO j = j0, jcol+1, -nnb
631 CALL sorm22(
'Left',
'Transpose', 2*nnb, cola, nnb,
632 $ nnb, work( ppwo ), 2*nnb,
633 $ a( j, jcol+nnb ), lda, work( pw ),
639 CALL sgemm(
'Transpose',
'No Transpose', 2*nnb,
640 $ cola, 2*nnb, one, work( ppwo ), 2*nnb,
641 $ a( j, jcol+nnb ), lda, zero, work( pw ),
643 CALL slacpy(
'All', 2*nnb, cola, work( pw ), 2*nnb,
644 $ a( j, jcol+nnb ), lda )
646 ppwo = ppwo + 4*nnb*nnb
654 topq = max( 2, j - jcol + 1 )
660 CALL sgemm(
'No Transpose',
'No Transpose', nh,
661 $ nblst, nblst, one, q( topq, j ), ldq,
662 $ work, nblst, zero, work( pw ), nh )
663 CALL slacpy(
'All', nh, nblst, work( pw ), nh,
664 $ q( topq, j ), ldq )
665 ppwo = nblst*nblst + 1
667 DO j = j0, jcol+1, -nnb
669 topq = max( 2, j - jcol + 1 )
676 CALL sorm22(
'Right',
'No Transpose', nh, 2*nnb,
677 $ nnb, nnb, work( ppwo ), 2*nnb,
678 $ q( topq, j ), ldq, work( pw ),
684 CALL sgemm(
'No Transpose',
'No Transpose', nh,
685 $ 2*nnb, 2*nnb, one, q( topq, j ), ldq,
686 $ work( ppwo ), 2*nnb, zero, work( pw ),
688 CALL slacpy(
'All', nh, 2*nnb, work( pw ), nh,
689 $ q( topq, j ), ldq )
691 ppwo = ppwo + 4*nnb*nnb
697 IF ( wantz .OR. top.GT.0 )
THEN
702 CALL slaset(
'All', nblst, nblst, zero, one, work,
704 pw = nblst * nblst + 1
706 CALL slaset(
'All', 2*nnb, 2*nnb, zero, one,
707 $ work( pw ), 2*nnb )
713 DO j = jcol, jcol+nnb-1
714 ppw = ( nblst + 1 )*( nblst - 2 ) - j + jcol + 1
716 jrow = j + n2nb*nnb + 2
722 DO jj = ppw, ppw+len-1
723 temp = work( jj + nblst )
724 work( jj + nblst ) = c*temp - s*work( jj )
725 work( jj ) = s*temp + c*work( jj )
728 ppw = ppw - nblst - 1
731 ppwo = nblst*nblst + ( nnb+j-jcol-1 )*2*nnb + nnb
733 DO jrow = j0, j+2, -nnb
736 DO i = jrow+nnb-1, jrow, -1
741 DO jj = ppw, ppw+len-1
742 temp = work( jj + 2*nnb )
743 work( jj + 2*nnb ) = c*temp - s*work( jj )
744 work( jj ) = s*temp + c*work( jj )
747 ppw = ppw - 2*nnb - 1
749 ppwo = ppwo + 4*nnb*nnb
754 CALL slaset(
'Lower', ihi - jcol - 1, nnb, zero, zero,
755 $ a( jcol + 2, jcol ), lda )
756 CALL slaset(
'Lower', ihi - jcol - 1, nnb, zero, zero,
757 $ b( jcol + 2, jcol ), ldb )
764 CALL sgemm(
'No Transpose',
'No Transpose', top,
765 $ nblst, nblst, one, a( 1, j ), lda,
766 $ work, nblst, zero, work( pw ), top )
767 CALL slacpy(
'All', top, nblst, work( pw ), top,
769 ppwo = nblst*nblst + 1
771 DO j = j0, jcol+1, -nnb
776 CALL sorm22(
'Right',
'No Transpose', top, 2*nnb,
777 $ nnb, nnb, work( ppwo ), 2*nnb,
778 $ a( 1, j ), lda, work( pw ),
784 CALL sgemm(
'No Transpose',
'No Transpose', top,
785 $ 2*nnb, 2*nnb, one, a( 1, j ), lda,
786 $ work( ppwo ), 2*nnb, zero,
788 CALL slacpy(
'All', top, 2*nnb, work( pw ), top,
791 ppwo = ppwo + 4*nnb*nnb
795 CALL sgemm(
'No Transpose',
'No Transpose', top,
796 $ nblst, nblst, one, b( 1, j ), ldb,
797 $ work, nblst, zero, work( pw ), top )
798 CALL slacpy(
'All', top, nblst, work( pw ), top,
800 ppwo = nblst*nblst + 1
802 DO j = j0, jcol+1, -nnb
807 CALL sorm22(
'Right',
'No Transpose', top, 2*nnb,
808 $ nnb, nnb, work( ppwo ), 2*nnb,
809 $ b( 1, j ), ldb, work( pw ),
815 CALL sgemm(
'No Transpose',
'No Transpose', top,
816 $ 2*nnb, 2*nnb, one, b( 1, j ), ldb,
817 $ work( ppwo ), 2*nnb, zero,
819 CALL slacpy(
'All', top, 2*nnb, work( pw ), top,
822 ppwo = ppwo + 4*nnb*nnb
831 topq = max( 2, j - jcol + 1 )
837 CALL sgemm(
'No Transpose',
'No Transpose', nh,
838 $ nblst, nblst, one, z( topq, j ), ldz,
839 $ work, nblst, zero, work( pw ), nh )
840 CALL slacpy(
'All', nh, nblst, work( pw ), nh,
841 $ z( topq, j ), ldz )
842 ppwo = nblst*nblst + 1
844 DO j = j0, jcol+1, -nnb
846 topq = max( 2, j - jcol + 1 )
853 CALL sorm22(
'Right',
'No Transpose', nh, 2*nnb,
854 $ nnb, nnb, work( ppwo ), 2*nnb,
855 $ z( topq, j ), ldz, work( pw ),
861 CALL sgemm(
'No Transpose',
'No Transpose', nh,
862 $ 2*nnb, 2*nnb, one, z( topq, j ), ldz,
863 $ work( ppwo ), 2*nnb, zero, work( pw ),
865 CALL slacpy(
'All', nh, 2*nnb, work( pw ), nh,
866 $ z( topq, j ), ldz )
868 ppwo = ppwo + 4*nnb*nnb
879 IF ( jcol.NE.ilo )
THEN
887 $
CALL sgghrd( compq2, compz2, n, jcol, ihi, a, lda, b, ldb, q,
888 $ ldq, z, ldz, ierr )
889 work( 1 ) = sroundup_lwork( lwkopt )
subroutine xerbla(srname, info)
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine sgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
SGEMV
subroutine sgghd3(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, work, lwork, info)
SGGHD3
subroutine sgghrd(compq, compz, n, ilo, ihi, a, lda, b, ldb, q, ldq, z, ldz, info)
SGGHRD
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
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.
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT
subroutine strmv(uplo, trans, diag, n, a, lda, x, incx)
STRMV
subroutine sorm22(side, trans, m, n, n1, n2, q, ldq, c, ldc, work, lwork, info)
SORM22 multiplies a general matrix by a banded orthogonal matrix.