269 SUBROUTINE cgesvdx( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
270 $ il, iu, ns, s, u, ldu, vt, ldvt, work,
271 $ lwork, rwork, iwork, info )
279 CHARACTER JOBU, JOBVT, RANGE
280 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
285 REAL S( * ), RWORK( * )
286 COMPLEX A( lda, * ), U( ldu, * ), VT( ldvt, * ),
294 parameter ( czero = ( 0.0e0, 0.0e0 ),
295 $ cone = ( 1.0e0, 0.0e0 ) )
297 parameter ( zero = 0.0e0, one = 1.0e0 )
300 CHARACTER JOBZ, RNGTGK
301 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
302 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
303 $ itau, itaup, itauq, itemp, itempr, itgkz,
304 $ iutgk, j, k, maxwrk, minmn, minwrk, mnthr
305 REAL ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
318 EXTERNAL lsame, ilaenv, slamch, clange
321 INTRINSIC max, min, sqrt
329 abstol = 2*slamch(
'S')
330 lquery = ( lwork.EQ.-1 )
333 wantu = lsame( jobu,
'V' )
334 wantvt = lsame( jobvt,
'V' )
335 IF( wantu .OR. wantvt )
THEN
340 alls = lsame( range,
'A' )
341 vals = lsame( range,
'V' )
342 inds = lsame( range,
'I' )
345 IF( .NOT.lsame( jobu,
'V' ) .AND.
346 $ .NOT.lsame( jobu,
'N' ) )
THEN
348 ELSE IF( .NOT.lsame( jobvt,
'V' ) .AND.
349 $ .NOT.lsame( jobvt,
'N' ) )
THEN
351 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) )
THEN
353 ELSE IF( m.LT.0 )
THEN
355 ELSE IF( n.LT.0 )
THEN
357 ELSE IF( m.GT.lda )
THEN
359 ELSE IF( minmn.GT.0 )
THEN
361 IF( vl.LT.zero )
THEN
363 ELSE IF( vu.LE.vl )
THEN
367 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) )
THEN
369 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn )
THEN
374 IF( wantu .AND. ldu.LT.m )
THEN
376 ELSE IF( wantvt )
THEN
378 IF( ldvt.LT.iu-il+1 )
THEN
381 ELSE IF( ldvt.LT.minmn )
THEN
398 IF( minmn.GT.0 )
THEN
400 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0, 0 )
401 IF( m.GE.mnthr )
THEN
406 maxwrk = n + n*ilaenv(1,
'CGEQRF',
' ',m,n,-1,-1)
408 $ n*n+2*n+2*n*ilaenv(1,
'CGEBRD',
' ',n,n,-1,-1))
409 IF (wantu .OR. wantvt)
THEN
411 $ n*n+2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
418 maxwrk = 2*n + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,-1)
419 IF (wantu .OR. wantvt)
THEN
421 $ 2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
425 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0, 0 )
426 IF( n.GE.mnthr )
THEN
431 maxwrk = m + m*ilaenv(1,
'CGELQF',
' ',m,n,-1,-1)
433 $ m*m+2*m+2*m*ilaenv(1,
'CGEBRD',
' ',m,m,-1,-1))
434 IF (wantu .OR. wantvt)
THEN
436 $ m*m+2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
444 maxwrk = 2*m + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,-1)
445 IF (wantu .OR. wantvt)
THEN
447 $ 2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
452 maxwrk = max( maxwrk, minwrk )
453 work( 1 ) = cmplx(
REAL( MAXWRK ), ZERO )
455 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
461 CALL xerbla(
'CGESVDX', -info )
463 ELSE IF( lquery )
THEN
469 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
492 smlnum = sqrt( slamch(
'S' ) ) / eps
493 bignum = one / smlnum
497 anrm = clange(
'M', m, n, a, lda, dum )
499 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
501 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
502 ELSE IF( anrm.GT.bignum )
THEN
504 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
513 IF( m.GE.mnthr )
THEN
525 CALL cgeqrf( m, n, a, lda, work( itau ), work( itemp ),
526 $ lwork-itemp+1, info )
538 CALL clacpy(
'U', n, n, a, lda, work( iqrf ), n )
539 CALL claset(
'L', n-1, n-1, czero, czero,
540 $ work( iqrf+1 ), n )
541 CALL cgebrd( n, n, work( iqrf ), n, rwork( id ),
542 $ rwork( ie ), work( itauq ), work( itaup ),
543 $ work( itemp ), lwork-itemp+1, info )
544 itempr = itgkz + n*(n*2+1)
549 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
550 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
551 $ rwork( itgkz ), n*2, rwork( itempr ),
560 u( j, i ) = cmplx( rwork( k ), zero )
565 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
570 CALL cunmbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
571 $ work( itauq ), u, ldu, work( itemp ),
572 $ lwork-itemp+1, info )
577 CALL cunmqr(
'L',
'N', m, ns, n, a, lda,
578 $ work( itau ), u, ldu, work( itemp ),
579 $ lwork-itemp+1, info )
588 vt( i, j ) = cmplx( rwork( k ), zero )
597 CALL cunmbr(
'P',
'R',
'C', ns, n, n, work( iqrf ), n,
598 $ work( itaup ), vt, ldvt, work( itemp ),
599 $ lwork-itemp+1, info )
617 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
618 $ work( itauq ), work( itaup ), work( itemp ),
619 $ lwork-itemp+1, info )
620 itempr = itgkz + n*(n*2+1)
625 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
626 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
627 $ rwork( itgkz ), n*2, rwork( itempr ),
636 u( j, i ) = cmplx( rwork( k ), zero )
641 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
646 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
647 $ work( itauq ), u, ldu, work( itemp ),
648 $ lwork-itemp+1, ierr )
657 vt( i, j ) = cmplx( rwork( k ), zero )
666 CALL cunmbr(
'P',
'R',
'C', ns, n, n, a, lda,
667 $ work( itaup ), vt, ldvt, work( itemp ),
668 $ lwork-itemp+1, ierr )
676 IF( n.GE.mnthr )
THEN
688 CALL cgelqf( m, n, a, lda, work( itau ), work( itemp ),
689 $ lwork-itemp+1, info )
701 CALL clacpy(
'L', m, m, a, lda, work( ilqf ), m )
702 CALL claset(
'U', m-1, m-1, czero, czero,
703 $ work( ilqf+m ), m )
704 CALL cgebrd( m, m, work( ilqf ), m, rwork( id ),
705 $ rwork( ie ), work( itauq ), work( itaup ),
706 $ work( itemp ), lwork-itemp+1, info )
707 itempr = itgkz + m*(m*2+1)
712 CALL sbdsvdx(
'U', jobz, rngtgk, m, rwork( id ),
713 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
714 $ rwork( itgkz ), m*2, rwork( itempr ),
723 u( j, i ) = cmplx( rwork( k ), zero )
732 CALL cunmbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
733 $ work( itauq ), u, ldu, work( itemp ),
734 $ lwork-itemp+1, info )
743 vt( i, j ) = cmplx( rwork( k ), zero )
748 CALL claset(
'A', ns, n-m, czero, czero,
749 $ vt( 1,m+1 ), ldvt )
754 CALL cunmbr(
'P',
'R',
'C', ns, m, m, work( ilqf ), m,
755 $ work( itaup ), vt, ldvt, work( itemp ),
756 $ lwork-itemp+1, info )
761 CALL cunmlq(
'R',
'N', ns, n, m, a, lda,
762 $ work( itau ), vt, ldvt, work( itemp ),
763 $ lwork-itemp+1, info )
781 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
782 $ work( itauq ), work( itaup ), work( itemp ),
783 $ lwork-itemp+1, info )
784 itempr = itgkz + m*(m*2+1)
789 CALL sbdsvdx(
'L', jobz, rngtgk, m, rwork( id ),
790 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
791 $ rwork( itgkz ), m*2, rwork( itempr ),
800 u( j, i ) = cmplx( rwork( k ), zero )
809 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
810 $ work( itauq ), u, ldu, work( itemp ),
811 $ lwork-itemp+1, info )
820 vt( i, j ) = cmplx( rwork( k ), zero )
825 CALL claset(
'A', ns, n-m, czero, czero,
826 $ vt( 1,m+1 ), ldvt )
831 CALL cunmbr(
'P',
'R',
'C', ns, n, m, a, lda,
832 $ work( itaup ), vt, ldvt, work( itemp ),
833 $ lwork-itemp+1, info )
842 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1,
845 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
851 work( 1 ) = cmplx(
REAL( MAXWRK ), ZERO )
subroutine cunmbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMBR
subroutine clascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
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 cgesvdx(JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU, IL, IU, NS, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, IWORK, INFO)
CGESVDX computes the singular value decomposition (SVD) for GE matrices
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine cunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMQR
subroutine cgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGELQF
subroutine claset(UPLO, M, N, ALPHA, BETA, A, LDA)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine sbdsvdx(UPLO, JOBZ, RANGE, N, D, E, VL, VU, IL, IU, NS, S, Z, LDZ, WORK, IWORK, INFO)
SBDSVDX
subroutine cgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGEQRF
subroutine cgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
CGEBRD
subroutine clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
subroutine cunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMLQ