262 SUBROUTINE sgesvdx( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
263 $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
264 $ LWORK, IWORK, INFO )
272 CHARACTER JOBU, JOBVT, RANGE
273 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
278 REAL A( LDA, * ), S( * ), U( LDU, * ),
279 $ vt( ldvt, * ), work( * )
286 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
289 CHARACTER JOBZ, RNGTGK
290 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
291 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
292 $ itau, itaup, itauq, itemp, itgkz, iutgk,
293 $ j, maxwrk, minmn, minwrk, mnthr
294 REAL ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
308 EXTERNAL lsame, ilaenv, slamch, slange
311 INTRINSIC max, min, sqrt
319 abstol = 2*slamch(
'S')
320 lquery = ( lwork.EQ.-1 )
323 wantu = lsame( jobu,
'V' )
324 wantvt = lsame( jobvt,
'V' )
325 IF( wantu .OR. wantvt )
THEN
330 alls = lsame( range,
'A' )
331 vals = lsame( range,
'V' )
332 inds = lsame( range,
'I' )
335 IF( .NOT.lsame( jobu,
'V' ) .AND.
336 $ .NOT.lsame( jobu,
'N' ) )
THEN
338 ELSE IF( .NOT.lsame( jobvt,
'V' ) .AND.
339 $ .NOT.lsame( jobvt,
'N' ) )
THEN
341 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) )
THEN
343 ELSE IF( m.LT.0 )
THEN
345 ELSE IF( n.LT.0 )
THEN
347 ELSE IF( m.GT.lda )
THEN
349 ELSE IF( minmn.GT.0 )
THEN
351 IF( vl.LT.zero )
THEN
353 ELSE IF( vu.LE.vl )
THEN
357 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) )
THEN
359 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn )
THEN
364 IF( wantu .AND. ldu.LT.m )
THEN
366 ELSE IF( wantvt )
THEN
368 IF( ldvt.LT.iu-il+1 )
THEN
371 ELSE IF( ldvt.LT.minmn )
THEN
388 IF( minmn.GT.0 )
THEN
390 mnthr = ilaenv( 6,
'SGESVD', jobu // jobvt, m, n, 0, 0 )
391 IF( m.GE.mnthr )
THEN
396 $ n*ilaenv( 1,
'SGEQRF',
' ', m, n, -1, -1 )
397 maxwrk = max( maxwrk, n*(n+5) + 2*n*
398 $ ilaenv( 1,
'SGEBRD',
' ', n, n, -1, -1 ) )
400 maxwrk = max(maxwrk,n*(n*3+6)+n*
401 $ ilaenv( 1,
'SORMQR',
' ', n, n, -1, -1 ) )
404 maxwrk = max(maxwrk,n*(n*3+6)+n*
405 $ ilaenv( 1,
'SORMLQ',
' ', n, n, -1, -1 ) )
412 maxwrk = 4*n + ( m+n )*
413 $ ilaenv( 1,
'SGEBRD',
' ', m, n, -1, -1 )
415 maxwrk = max(maxwrk,n*(n*2+5)+n*
416 $ ilaenv( 1,
'SORMQR',
' ', n, n, -1, -1 ) )
419 maxwrk = max(maxwrk,n*(n*2+5)+n*
420 $ ilaenv( 1,
'SORMLQ',
' ', n, n, -1, -1 ) )
422 minwrk = max(n*(n*2+19),4*n+m)
425 mnthr = ilaenv( 6,
'SGESVD', jobu // jobvt, m, n, 0, 0 )
426 IF( n.GE.mnthr )
THEN
431 $ m*ilaenv( 1,
'SGELQF',
' ', m, n, -1, -1 )
432 maxwrk = max( maxwrk, m*(m+5) + 2*m*
433 $ ilaenv( 1,
'SGEBRD',
' ', m, m, -1, -1 ) )
435 maxwrk = max(maxwrk,m*(m*3+6)+m*
436 $ ilaenv( 1,
'SORMQR',
' ', m, m, -1, -1 ) )
439 maxwrk = max(maxwrk,m*(m*3+6)+m*
440 $ ilaenv( 1,
'SORMLQ',
' ', m, m, -1, -1 ) )
447 maxwrk = 4*m + ( m+n )*
448 $ ilaenv( 1,
'SGEBRD',
' ', m, n, -1, -1 )
450 maxwrk = max(maxwrk,m*(m*2+5)+m*
451 $ ilaenv( 1,
'SORMQR',
' ', m, m, -1, -1 ) )
454 maxwrk = max(maxwrk,m*(m*2+5)+m*
455 $ ilaenv( 1,
'SORMLQ',
' ', m, m, -1, -1 ) )
457 minwrk = max(m*(m*2+19),4*m+n)
461 maxwrk = max( maxwrk, minwrk )
462 work( 1 ) = real( maxwrk )
464 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
470 CALL xerbla(
'SGESVDX', -info )
472 ELSE IF( lquery )
THEN
478 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
501 smlnum = sqrt( slamch(
'S' ) ) / eps
502 bignum = one / smlnum
506 anrm = slange(
'M', m, n, a, lda, dum )
508 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
510 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
511 ELSE IF( anrm.GT.bignum )
THEN
513 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
522 IF( m.GE.mnthr )
THEN
534 CALL sgeqrf( m, n, a, lda, work( itau ), work( itemp ),
535 $ lwork-itemp+1, info )
546 CALL slacpy(
'U', n, n, a, lda, work( iqrf ), n )
547 CALL slaset(
'L', n-1, n-1, zero, zero, work( iqrf+1 ), n )
548 CALL sgebrd( n, n, work( iqrf ), n, work( id ), work( ie ),
549 $ work( itauq ), work( itaup ), work( itemp ),
550 $ lwork-itemp+1, info )
556 itemp = itgkz + n*(n*2+1)
557 CALL sbdsvdx(
'U', jobz, rngtgk, n, work( id ), work( ie ),
558 $ vl, vu, iltgk, iutgk, ns, s, work( itgkz ),
559 $ n*2, work( itemp ), iwork, info)
566 CALL scopy( n, work( j ), 1, u( 1,i ), 1 )
569 CALL slaset(
'A', m-n, ns, zero, zero, u( n+1,1 ), ldu )
574 CALL sormbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
575 $ work( itauq ), u, ldu, work( itemp ),
576 $ lwork-itemp+1, info )
581 CALL sormqr(
'L',
'N', m, ns, n, a, lda,
582 $ work( itau ), u, ldu, work( itemp ),
583 $ lwork-itemp+1, info )
591 CALL scopy( n, work( j ), 1, vt( i,1 ), ldvt )
598 CALL sormbr(
'P',
'R',
'T', ns, n, n, work( iqrf ), n,
599 $ work( itaup ), vt, ldvt, work( itemp ),
600 $ lwork-itemp+1, info )
617 CALL sgebrd( m, n, a, lda, work( id ), work( ie ),
618 $ work( itauq ), work( itaup ), work( itemp ),
619 $ lwork-itemp+1, info )
625 itemp = itgkz + n*(n*2+1)
626 CALL sbdsvdx(
'U', jobz, rngtgk, n, work( id ), work( ie ),
627 $ vl, vu, iltgk, iutgk, ns, s, work( itgkz ),
628 $ n*2, work( itemp ), iwork, info)
635 CALL scopy( n, work( j ), 1, u( 1,i ), 1 )
638 CALL slaset(
'A', m-n, ns, zero, zero, u( n+1,1 ), ldu )
643 CALL sormbr(
'Q',
'L',
'N', m, ns, n, a, lda,
644 $ work( itauq ), u, ldu, work( itemp ),
645 $ lwork-itemp+1, ierr )
653 CALL scopy( n, work( j ), 1, vt( i,1 ), ldvt )
660 CALL sormbr(
'P',
'R',
'T', ns, n, n, a, lda,
661 $ work( itaup ), vt, ldvt, work( itemp ),
662 $ lwork-itemp+1, ierr )
670 IF( n.GE.mnthr )
THEN
682 CALL sgelqf( m, n, a, lda, work( itau ), work( itemp ),
683 $ lwork-itemp+1, info )
694 CALL slacpy(
'L', m, m, a, lda, work( ilqf ), m )
695 CALL slaset(
'U', m-1, m-1, zero, zero, work( ilqf+m ), m )
696 CALL sgebrd( m, m, work( ilqf ), m, work( id ), work( ie ),
697 $ work( itauq ), work( itaup ), work( itemp ),
698 $ lwork-itemp+1, info )
704 itemp = itgkz + m*(m*2+1)
705 CALL sbdsvdx(
'U', jobz, rngtgk, m, work( id ), work( ie ),
706 $ vl, vu, iltgk, iutgk, ns, s, work( itgkz ),
707 $ m*2, work( itemp ), iwork, info)
714 CALL scopy( m, work( j ), 1, u( 1,i ), 1 )
721 CALL sormbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
722 $ work( itauq ), u, ldu, work( itemp ),
723 $ lwork-itemp+1, info )
731 CALL scopy( m, work( j ), 1, vt( i,1 ), ldvt )
734 CALL slaset(
'A', ns, n-m, zero, zero, vt( 1,m+1 ), ldvt)
739 CALL sormbr(
'P',
'R',
'T', ns, m, m, work( ilqf ), m,
740 $ work( itaup ), vt, ldvt, work( itemp ),
741 $ lwork-itemp+1, info )
746 CALL sormlq(
'R',
'N', ns, n, m, a, lda,
747 $ work( itau ), vt, ldvt, work( itemp ),
748 $ lwork-itemp+1, info )
765 CALL sgebrd( m, n, a, lda, work( id ), work( ie ),
766 $ work( itauq ), work( itaup ), work( itemp ),
767 $ lwork-itemp+1, info )
773 itemp = itgkz + m*(m*2+1)
774 CALL sbdsvdx(
'L', jobz, rngtgk, m, work( id ), work( ie ),
775 $ vl, vu, iltgk, iutgk, ns, s, work( itgkz ),
776 $ m*2, work( itemp ), iwork, info)
783 CALL scopy( m, work( j ), 1, u( 1,i ), 1 )
790 CALL sormbr(
'Q',
'L',
'N', m, ns, n, a, lda,
791 $ work( itauq ), u, ldu, work( itemp ),
792 $ lwork-itemp+1, info )
800 CALL scopy( m, work( j ), 1, vt( i,1 ), ldvt )
803 CALL slaset(
'A', ns, n-m, zero, zero, vt( 1,m+1 ), ldvt)
808 CALL sormbr(
'P',
'R',
'T', ns, n, m, a, lda,
809 $ work( itaup ), vt, ldvt, work( itemp ),
810 $ lwork-itemp+1, info )
819 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1,
822 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
828 work( 1 ) = real( maxwrk )