258 SUBROUTINE sgesvdx( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
259 $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
260 $ LWORK, IWORK, INFO )
267 CHARACTER JOBU, JOBVT, RANGE
268 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
273 REAL A( LDA, * ), S( * ), U( LDU, * ),
274 $ vt( ldvt, * ), work( * )
281 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
284 CHARACTER JOBZ, RNGTGK
285 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
286 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
287 $ itau, itaup, itauq, itemp, itgkz, iutgk,
288 $ j, maxwrk, minmn, minwrk, mnthr
289 REAL ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
303 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
304 EXTERNAL lsame, ilaenv, slamch, slange,
308 INTRINSIC max, min, sqrt
316 abstol = 2*slamch(
'S')
317 lquery = ( lwork.EQ.-1 )
320 wantu = lsame( jobu,
'V' )
321 wantvt = lsame( jobvt,
'V' )
322 IF( wantu .OR. wantvt )
THEN
327 alls = lsame( range,
'A' )
328 vals = lsame( range,
'V' )
329 inds = lsame( range,
'I' )
332 IF( .NOT.lsame( jobu,
'V' ) .AND.
333 $ .NOT.lsame( jobu,
'N' ) )
THEN
335 ELSE IF( .NOT.lsame( jobvt,
'V' ) .AND.
336 $ .NOT.lsame( jobvt,
'N' ) )
THEN
338 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) )
THEN
340 ELSE IF( m.LT.0 )
THEN
342 ELSE IF( n.LT.0 )
THEN
344 ELSE IF( m.GT.lda )
THEN
346 ELSE IF( minmn.GT.0 )
THEN
348 IF( vl.LT.zero )
THEN
350 ELSE IF( vu.LE.vl )
THEN
354 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) )
THEN
356 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn )
THEN
361 IF( wantu .AND. ldu.LT.m )
THEN
363 ELSE IF( wantvt )
THEN
365 IF( ldvt.LT.iu-il+1 )
THEN
368 ELSE IF( ldvt.LT.minmn )
THEN
385 IF( minmn.GT.0 )
THEN
387 mnthr = ilaenv( 6,
'SGESVD', jobu // jobvt, m, n, 0,
389 IF( m.GE.mnthr )
THEN
394 $ n*ilaenv( 1,
'SGEQRF',
' ', m, n, -1, -1 )
395 maxwrk = max( maxwrk, n*(n+5) + 2*n*
396 $ ilaenv( 1,
'SGEBRD',
' ', n, n, -1, -1 ) )
398 maxwrk = max(maxwrk,n*(n*3+6)+n*
399 $ ilaenv( 1,
'SORMQR',
' ', n, n, -1, -1 ) )
402 maxwrk = max(maxwrk,n*(n*3+6)+n*
403 $ ilaenv( 1,
'SORMLQ',
' ', n, n, -1, -1 ) )
410 maxwrk = 4*n + ( m+n )*
411 $ ilaenv( 1,
'SGEBRD',
' ', m, n, -1, -1 )
413 maxwrk = max(maxwrk,n*(n*2+5)+n*
414 $ ilaenv( 1,
'SORMQR',
' ', n, n, -1, -1 ) )
417 maxwrk = max(maxwrk,n*(n*2+5)+n*
418 $ ilaenv( 1,
'SORMLQ',
' ', n, n, -1, -1 ) )
420 minwrk = max(n*(n*2+19),4*n+m)
423 mnthr = ilaenv( 6,
'SGESVD', jobu // jobvt, m, n, 0,
425 IF( n.GE.mnthr )
THEN
430 $ m*ilaenv( 1,
'SGELQF',
' ', m, n, -1, -1 )
431 maxwrk = max( maxwrk, m*(m+5) + 2*m*
432 $ ilaenv( 1,
'SGEBRD',
' ', m, m, -1, -1 ) )
434 maxwrk = max(maxwrk,m*(m*3+6)+m*
435 $ ilaenv( 1,
'SORMQR',
' ', m, m, -1, -1 ) )
438 maxwrk = max(maxwrk,m*(m*3+6)+m*
439 $ ilaenv( 1,
'SORMLQ',
' ', m, m, -1, -1 ) )
446 maxwrk = 4*m + ( m+n )*
447 $ ilaenv( 1,
'SGEBRD',
' ', m, n, -1, -1 )
449 maxwrk = max(maxwrk,m*(m*2+5)+m*
450 $ ilaenv( 1,
'SORMQR',
' ', m, m, -1, -1 ) )
453 maxwrk = max(maxwrk,m*(m*2+5)+m*
454 $ ilaenv( 1,
'SORMLQ',
' ', m, m, -1, -1 ) )
456 minwrk = max(m*(m*2+19),4*m+n)
460 maxwrk = max( maxwrk, minwrk )
461 work( 1 ) = sroundup_lwork( maxwrk )
463 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
469 CALL xerbla(
'SGESVDX', -info )
471 ELSE IF( lquery )
THEN
477 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
500 smlnum = sqrt( slamch(
'S' ) ) / eps
501 bignum = one / smlnum
505 anrm = slange(
'M', m, n, a, lda, dum )
507 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
509 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
510 ELSE IF( anrm.GT.bignum )
THEN
512 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
521 IF( m.GE.mnthr )
THEN
533 CALL sgeqrf( m, n, a, lda, work( itau ), work( itemp ),
534 $ lwork-itemp+1, info )
545 CALL slacpy(
'U', n, n, a, lda, work( iqrf ), n )
546 CALL slaset(
'L', n-1, n-1, zero, zero, work( iqrf+1 ),
548 CALL sgebrd( n, n, work( iqrf ), n, work( id ),
550 $ work( itauq ), work( itaup ), work( itemp ),
551 $ lwork-itemp+1, info )
557 itemp = itgkz + n*(n*2+1)
558 CALL sbdsvdx(
'U', jobz, rngtgk, n, work( id ),
560 $ vl, vu, iltgk, iutgk, ns, s, work( itgkz ),
561 $ n*2, work( itemp ), iwork, info)
568 CALL scopy( n, work( j ), 1, u( 1,i ), 1 )
571 CALL slaset(
'A', m-n, ns, zero, zero, u( n+1,1 ),
577 CALL sormbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
578 $ work( itauq ), u, ldu, work( itemp ),
579 $ lwork-itemp+1, info )
584 CALL sormqr(
'L',
'N', m, ns, n, a, lda,
585 $ work( itau ), u, ldu, work( itemp ),
586 $ lwork-itemp+1, info )
594 CALL scopy( n, work( j ), 1, vt( i,1 ), ldvt )
601 CALL sormbr(
'P',
'R',
'T', ns, n, n, work( iqrf ), n,
602 $ work( itaup ), vt, ldvt, work( itemp ),
603 $ lwork-itemp+1, info )
620 CALL sgebrd( m, n, a, lda, work( id ), work( ie ),
621 $ work( itauq ), work( itaup ), work( itemp ),
622 $ lwork-itemp+1, info )
628 itemp = itgkz + n*(n*2+1)
629 CALL sbdsvdx(
'U', jobz, rngtgk, n, work( id ),
631 $ vl, vu, iltgk, iutgk, ns, s, work( itgkz ),
632 $ n*2, work( itemp ), iwork, info)
639 CALL scopy( n, work( j ), 1, u( 1,i ), 1 )
642 CALL slaset(
'A', m-n, ns, zero, zero, u( n+1,1 ),
648 CALL sormbr(
'Q',
'L',
'N', m, ns, n, a, lda,
649 $ work( itauq ), u, ldu, work( itemp ),
650 $ lwork-itemp+1, ierr )
658 CALL scopy( n, work( j ), 1, vt( i,1 ), ldvt )
665 CALL sormbr(
'P',
'R',
'T', ns, n, n, a, lda,
666 $ work( itaup ), vt, ldvt, work( itemp ),
667 $ lwork-itemp+1, ierr )
675 IF( n.GE.mnthr )
THEN
687 CALL sgelqf( m, n, a, lda, work( itau ), work( itemp ),
688 $ lwork-itemp+1, info )
699 CALL slacpy(
'L', m, m, a, lda, work( ilqf ), m )
700 CALL slaset(
'U', m-1, m-1, zero, zero, work( ilqf+m ),
702 CALL sgebrd( m, m, work( ilqf ), m, work( id ),
704 $ work( itauq ), work( itaup ), work( itemp ),
705 $ lwork-itemp+1, info )
711 itemp = itgkz + m*(m*2+1)
712 CALL sbdsvdx(
'U', jobz, rngtgk, m, work( id ),
714 $ vl, vu, iltgk, iutgk, ns, s, work( itgkz ),
715 $ m*2, work( itemp ), iwork, info)
722 CALL scopy( m, work( j ), 1, u( 1,i ), 1 )
729 CALL sormbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
730 $ work( itauq ), u, ldu, work( itemp ),
731 $ lwork-itemp+1, info )
739 CALL scopy( m, work( j ), 1, vt( i,1 ), ldvt )
742 CALL slaset(
'A', ns, n-m, zero, zero, vt( 1,m+1 ),
748 CALL sormbr(
'P',
'R',
'T', ns, m, m, work( ilqf ), m,
749 $ work( itaup ), vt, ldvt, work( itemp ),
750 $ lwork-itemp+1, info )
755 CALL sormlq(
'R',
'N', ns, n, m, a, lda,
756 $ work( itau ), vt, ldvt, work( itemp ),
757 $ lwork-itemp+1, info )
774 CALL sgebrd( m, n, a, lda, work( id ), work( ie ),
775 $ work( itauq ), work( itaup ), work( itemp ),
776 $ lwork-itemp+1, info )
782 itemp = itgkz + m*(m*2+1)
783 CALL sbdsvdx(
'L', jobz, rngtgk, m, work( id ),
785 $ vl, vu, iltgk, iutgk, ns, s, work( itgkz ),
786 $ m*2, work( itemp ), iwork, info)
793 CALL scopy( m, work( j ), 1, u( 1,i ), 1 )
800 CALL sormbr(
'Q',
'L',
'N', m, ns, n, a, lda,
801 $ work( itauq ), u, ldu, work( itemp ),
802 $ lwork-itemp+1, info )
810 CALL scopy( m, work( j ), 1, vt( i,1 ), ldvt )
813 CALL slaset(
'A', ns, n-m, zero, zero, vt( 1,m+1 ),
819 CALL sormbr(
'P',
'R',
'T', ns, n, m, a, lda,
820 $ work( itaup ), vt, ldvt, work( itemp ),
821 $ lwork-itemp+1, info )
830 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1,
833 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
839 work( 1 ) = sroundup_lwork( maxwrk )