265 SUBROUTINE cgesvdx( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
266 $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
267 $ LWORK, RWORK, IWORK, INFO )
274 CHARACTER JOBU, JOBVT, RANGE
275 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
280 REAL S( * ), RWORK( * )
281 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
289 PARAMETER ( CZERO = ( 0.0e0, 0.0e0 ),
290 $ cone = ( 1.0e0, 0.0e0 ) )
292 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
295 CHARACTER JOBZ, RNGTGK
296 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
297 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
298 $ itau, itaup, itauq, itemp, itempr, itgkz,
299 $ iutgk, j, k, maxwrk, minmn, minwrk, mnthr
300 REAL ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
314 REAL SLAMCH, CLANGE, SROUNDUP_LWORK
315 EXTERNAL lsame, ilaenv, slamch,
316 $ clange, sroundup_lwork
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,
400 IF( m.GE.mnthr )
THEN
405 maxwrk = n + n*ilaenv(1,
'CGEQRF',
' ',m,n,-1,-1)
407 $ n*n+2*n+2*n*ilaenv(1,
'CGEBRD',
' ',n,n,-1,
409 IF (wantu .OR. wantvt)
THEN
411 $ n*n+2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,
419 maxwrk = 2*n + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,
421 IF (wantu .OR. wantvt)
THEN
423 $ 2*n+n*ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
427 mnthr = ilaenv( 6,
'CGESVD', jobu // jobvt, m, n, 0,
429 IF( n.GE.mnthr )
THEN
434 maxwrk = m + m*ilaenv(1,
'CGELQF',
' ',m,n,-1,-1)
436 $ m*m+2*m+2*m*ilaenv(1,
'CGEBRD',
' ',m,m,-1,
438 IF (wantu .OR. wantvt)
THEN
440 $ m*m+2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,
449 maxwrk = 2*m + (m+n)*ilaenv(1,
'CGEBRD',
' ',m,n,-1,
451 IF (wantu .OR. wantvt)
THEN
453 $ 2*m+m*ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
458 maxwrk = max( maxwrk, minwrk )
459 work( 1 ) = sroundup_lwork( maxwrk )
461 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
467 CALL xerbla(
'CGESVDX', -info )
469 ELSE IF( lquery )
THEN
475 IF( minmn.EQ.0 )
THEN
498 smlnum = sqrt( slamch(
'S' ) ) / eps
499 bignum = one / smlnum
503 anrm = clange(
'M', m, n, a, lda, dum )
505 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
507 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
508 ELSE IF( anrm.GT.bignum )
THEN
510 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
519 IF( m.GE.mnthr )
THEN
531 CALL cgeqrf( m, n, a, lda, work( itau ), work( itemp ),
532 $ lwork-itemp+1, info )
544 CALL clacpy(
'U', n, n, a, lda, work( iqrf ), n )
545 CALL claset(
'L', n-1, n-1, czero, czero,
546 $ work( iqrf+1 ), n )
547 CALL cgebrd( n, n, work( iqrf ), n, rwork( id ),
548 $ rwork( ie ), work( itauq ), work( itaup ),
549 $ work( itemp ), lwork-itemp+1, info )
550 itempr = itgkz + n*(n*2+1)
555 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
556 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
557 $ rwork( itgkz ), n*2, rwork( itempr ),
566 u( j, i ) = cmplx( rwork( k ), zero )
571 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ),
577 CALL cunmbr(
'Q',
'L',
'N', n, ns, n, work( iqrf ), n,
578 $ work( itauq ), u, ldu, work( itemp ),
579 $ lwork-itemp+1, info )
584 CALL cunmqr(
'L',
'N', m, ns, n, a, lda,
585 $ work( itau ), u, ldu, work( itemp ),
586 $ lwork-itemp+1, info )
595 vt( i, j ) = cmplx( rwork( k ), zero )
604 CALL cunmbr(
'P',
'R',
'C', ns, n, n, work( iqrf ), n,
605 $ work( itaup ), vt, ldvt, work( itemp ),
606 $ lwork-itemp+1, info )
624 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
625 $ work( itauq ), work( itaup ), work( itemp ),
626 $ lwork-itemp+1, info )
627 itempr = itgkz + n*(n*2+1)
632 CALL sbdsvdx(
'U', jobz, rngtgk, n, rwork( id ),
633 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
634 $ rwork( itgkz ), n*2, rwork( itempr ),
643 u( j, i ) = cmplx( rwork( k ), zero )
648 CALL claset(
'A', m-n, ns, czero, czero, u( n+1,1 ),
654 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
655 $ work( itauq ), u, ldu, work( itemp ),
656 $ lwork-itemp+1, ierr )
665 vt( i, j ) = cmplx( rwork( k ), zero )
674 CALL cunmbr(
'P',
'R',
'C', ns, n, n, a, lda,
675 $ work( itaup ), vt, ldvt, work( itemp ),
676 $ lwork-itemp+1, ierr )
684 IF( n.GE.mnthr )
THEN
696 CALL cgelqf( m, n, a, lda, work( itau ), work( itemp ),
697 $ lwork-itemp+1, info )
709 CALL clacpy(
'L', m, m, a, lda, work( ilqf ), m )
710 CALL claset(
'U', m-1, m-1, czero, czero,
711 $ work( ilqf+m ), m )
712 CALL cgebrd( m, m, work( ilqf ), m, rwork( id ),
713 $ rwork( ie ), work( itauq ), work( itaup ),
714 $ work( itemp ), lwork-itemp+1, info )
715 itempr = itgkz + m*(m*2+1)
720 CALL sbdsvdx(
'U', jobz, rngtgk, m, rwork( id ),
721 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
722 $ rwork( itgkz ), m*2, rwork( itempr ),
731 u( j, i ) = cmplx( rwork( k ), zero )
740 CALL cunmbr(
'Q',
'L',
'N', m, ns, m, work( ilqf ), m,
741 $ work( itauq ), u, ldu, work( itemp ),
742 $ lwork-itemp+1, info )
751 vt( i, j ) = cmplx( rwork( k ), zero )
756 CALL claset(
'A', ns, n-m, czero, czero,
757 $ vt( 1,m+1 ), ldvt )
762 CALL cunmbr(
'P',
'R',
'C', ns, m, m, work( ilqf ), m,
763 $ work( itaup ), vt, ldvt, work( itemp ),
764 $ lwork-itemp+1, info )
769 CALL cunmlq(
'R',
'N', ns, n, m, a, lda,
770 $ work( itau ), vt, ldvt, work( itemp ),
771 $ lwork-itemp+1, info )
789 CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
790 $ work( itauq ), work( itaup ), work( itemp ),
791 $ lwork-itemp+1, info )
792 itempr = itgkz + m*(m*2+1)
797 CALL sbdsvdx(
'L', jobz, rngtgk, m, rwork( id ),
798 $ rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
799 $ rwork( itgkz ), m*2, rwork( itempr ),
808 u( j, i ) = cmplx( rwork( k ), zero )
817 CALL cunmbr(
'Q',
'L',
'N', m, ns, n, a, lda,
818 $ work( itauq ), u, ldu, work( itemp ),
819 $ lwork-itemp+1, info )
828 vt( i, j ) = cmplx( rwork( k ), zero )
833 CALL claset(
'A', ns, n-m, czero, czero,
834 $ vt( 1,m+1 ), ldvt )
839 CALL cunmbr(
'P',
'R',
'C', ns, n, m, a, lda,
840 $ work( itaup ), vt, ldvt, work( itemp ),
841 $ lwork-itemp+1, info )
850 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1,
853 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1,
859 work( 1 ) = sroundup_lwork( maxwrk )