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 )
subroutine sgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
SGEBRD
subroutine sormlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMLQ
subroutine sormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMQR
subroutine sgesvdx(JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU, IL, IU, NS, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)
SGESVDX computes the singular value decomposition (SVD) for GE matrices
subroutine sormbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMBR
subroutine sgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
SGEQRF
subroutine sbdsvdx(UPLO, JOBZ, RANGE, N, D, E, VL, VU, IL, IU, NS, S, Z, LDZ, WORK, IWORK, INFO)
SBDSVDX
subroutine xerbla(SRNAME, INFO)
XERBLA
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 slascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine scopy(N, SX, INCX, SY, INCY)
SCOPY
subroutine sgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
SGELQF