267 SUBROUTINE cgesvdx( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
268 $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
269 $ LWORK, RWORK, IWORK, INFO )
276 CHARACTER JOBU, JOBVT, RANGE
277 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
282 REAL S( * ), RWORK( * )
283 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
291 PARAMETER ( CZERO = ( 0.0e0, 0.0e0 ),
292 $ cone = ( 1.0e0, 0.0e0 ) )
294 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
297 CHARACTER JOBZ, RNGTGK
298 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
299 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
300 $ itau, itaup, itauq, itemp, itempr, itgkz,
301 $ iutgk, j, k, maxwrk, minmn, minwrk, mnthr
302 REAL ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
316 EXTERNAL lsame, ilaenv, slamch, clange
319 INTRINSIC max, min, sqrt
327 abstol = 2*slamch(
'S')
328 lquery = ( lwork.EQ.-1 )
331 wantu = lsame( jobu,
'V' )
332 wantvt = lsame( jobvt,
'V' )
333 IF( wantu .OR. wantvt )
THEN
338 alls = lsame( range,
'A' )
339 vals = lsame( range,
'V' )
340 inds = lsame( range,
'I' )
343 IF( .NOT.lsame( jobu,
'V' ) .AND.
344 $ .NOT.lsame( jobu,
'N' ) )
THEN
346 ELSE IF( .NOT.lsame( jobvt,
'V' ) .AND.
347 $ .NOT.lsame( jobvt,
'N' ) )
THEN
349 ELSE IF( .NOT.( alls .OR. vals .OR. inds ) )
THEN
351 ELSE IF( m.LT.0 )
THEN
353 ELSE IF( n.LT.0 )
THEN
355 ELSE IF( m.GT.lda )
THEN
357 ELSE IF( minmn.GT.0 )
THEN
359 IF( vl.LT.zero )
THEN
361 ELSE IF( vu.LE.vl )
THEN
365 IF( il.LT.1 .OR. il.GT.max( 1, minmn ) )
THEN
367 ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn )
THEN
372 IF( wantu .AND. ldu.LT.m )
THEN
374 ELSE IF( wantvt )
THEN
376 IF( ldvt.LT.iu-il+1 )
THEN
379 ELSE IF( ldvt.LT.minmn )
THEN
396 IF( minmn.GT.0 )
THEN
398 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0, 0 )
399 IF( m.GE.mnthr )
THEN
404 maxwrk = n + n*ilaenv(1,
'CGEQRF',
' ',m,n,-1,-1)
406 $ n*n+2*n+2*n*ilaenv(1,
'CGEBRD',
' ',n,n,-1,-1))
407 IF (wantu .OR. wantvt)
THEN
409 $ n*n+2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
416 maxwrk = 2*n + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,-1)
417 IF (wantu .OR. wantvt)
THEN
419 $ 2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
423 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0, 0 )
424 IF( n.GE.mnthr )
THEN
429 maxwrk = m + m*ilaenv(1,
'CGELQF',
' ',m,n,-1,-1)
431 $ m*m+2*m+2*m*ilaenv(1,
'CGEBRD',
' ',m,m,-1,-1))
432 IF (wantu .OR. wantvt)
THEN
434 $ m*m+2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
442 maxwrk = 2*m + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,-1)
443 IF (wantu .OR. wantvt)
THEN
445 $ 2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
450 maxwrk = max( maxwrk, minwrk )
451 work( 1 ) = cmplx( real( maxwrk ), zero )
453 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
459 CALL xerbla(
'CGESVDX', -info )
461 ELSE IF( lquery )
THEN
467 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
490 smlnum = sqrt( slamch(
'S' ) ) / eps
491 bignum = one / smlnum
495 anrm = clange(
'M', m, n, a, lda, dum )
497 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
499 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
500 ELSE IF( anrm.GT.bignum )
THEN
502 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
511 IF( m.GE.mnthr )
THEN
523 CALL cgeqrf( m, n, a, lda, work( itau ), work( itemp ),
524 $ lwork-itemp+1, info )
536 CALL clacpy(
'U', n, n, a, lda, work( iqrf ), n )
537 CALL claset(
'L', n-1, n-1, czero, czero,
538 $ work( iqrf+1 ), n )
539 CALL cgebrd( n, n, work( iqrf ), n, rwork( id ),
540 $ rwork( ie ), work( itauq ), work( itaup ),
541 $ work( itemp ), lwork-itemp+1, info )
542 itempr = itgkz + n*(n*2+1)
547 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
548 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
549 $ rwork( itgkz ), n*2, rwork( itempr ),
558 u( j, i ) = cmplx( rwork( k ), zero )
563 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
568 CALL cunmbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
569 $ work( itauq ), u, ldu, work( itemp ),
570 $ lwork-itemp+1, info )
575 CALL cunmqr(
'L',
'N', m, ns, n, a, lda,
576 $ work( itau ), u, ldu, work( itemp ),
577 $ lwork-itemp+1, info )
586 vt( i, j ) = cmplx( rwork( k ), zero )
595 CALL cunmbr(
'P',
'R',
'C', ns, n, n, work( iqrf ), n,
596 $ work( itaup ), vt, ldvt, work( itemp ),
597 $ lwork-itemp+1, info )
615 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
616 $ work( itauq ), work( itaup ), work( itemp ),
617 $ lwork-itemp+1, info )
618 itempr = itgkz + n*(n*2+1)
623 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
624 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
625 $ rwork( itgkz ), n*2, rwork( itempr ),
634 u( j, i ) = cmplx( rwork( k ), zero )
639 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ), ldu)
644 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
645 $ work( itauq ), u, ldu, work( itemp ),
646 $ lwork-itemp+1, ierr )
655 vt( i, j ) = cmplx( rwork( k ), zero )
664 CALL cunmbr(
'P',
'R',
'C', ns, n, n, a, lda,
665 $ work( itaup ), vt, ldvt, work( itemp ),
666 $ lwork-itemp+1, ierr )
674 IF( n.GE.mnthr )
THEN
686 CALL cgelqf( m, n, a, lda, work( itau ), work( itemp ),
687 $ lwork-itemp+1, info )
699 CALL clacpy(
'L', m, m, a, lda, work( ilqf ), m )
700 CALL claset(
'U', m-1, m-1, czero, czero,
701 $ work( ilqf+m ), m )
702 CALL cgebrd( m, m, work( ilqf ), m, rwork( id ),
703 $ rwork( ie ), work( itauq ), work( itaup ),
704 $ work( itemp ), lwork-itemp+1, info )
705 itempr = itgkz + m*(m*2+1)
710 CALL sbdsvdx(
'U', jobz, rngtgk, m, rwork( id ),
711 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
712 $ rwork( itgkz ), m*2, rwork( itempr ),
721 u( j, i ) = cmplx( rwork( k ), zero )
730 CALL cunmbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
731 $ work( itauq ), u, ldu, work( itemp ),
732 $ lwork-itemp+1, info )
741 vt( i, j ) = cmplx( rwork( k ), zero )
746 CALL claset(
'A', ns, n-m, czero, czero,
747 $ vt( 1,m+1 ), ldvt )
752 CALL cunmbr(
'P',
'R',
'C', ns, m, m, work( ilqf ), m,
753 $ work( itaup ), vt, ldvt, work( itemp ),
754 $ lwork-itemp+1, info )
759 CALL cunmlq(
'R',
'N', ns, n, m, a, lda,
760 $ work( itau ), vt, ldvt, work( itemp ),
761 $ lwork-itemp+1, info )
779 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
780 $ work( itauq ), work( itaup ), work( itemp ),
781 $ lwork-itemp+1, info )
782 itempr = itgkz + m*(m*2+1)
787 CALL sbdsvdx(
'L', jobz, rngtgk, m, rwork( id ),
788 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
789 $ rwork( itgkz ), m*2, rwork( itempr ),
798 u( j, i ) = cmplx( rwork( k ), zero )
807 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
808 $ work( itauq ), u, ldu, work( itemp ),
809 $ lwork-itemp+1, info )
818 vt( i, j ) = cmplx( rwork( k ), zero )
823 CALL claset(
'A', ns, n-m, czero, czero,
824 $ vt( 1,m+1 ), ldvt )
829 CALL cunmbr(
'P',
'R',
'C', ns, n, m, a, lda,
830 $ work( itaup ), vt, ldvt, work( itemp ),
831 $ lwork-itemp+1, info )
840 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1,
843 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
849 work( 1 ) = cmplx( real( maxwrk ), zero )
subroutine xerbla(srname, info)
subroutine sbdsvdx(uplo, jobz, range, n, d, e, vl, vu, il, iu, ns, s, z, ldz, work, iwork, info)
SBDSVDX
subroutine cgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
CGEBRD
subroutine cgelqf(m, n, a, lda, tau, work, lwork, info)
CGELQF
subroutine cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
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 clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
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 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 cunmbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMBR
subroutine cunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMLQ
subroutine cunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMQR