224 SUBROUTINE cgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
225 $ WORK, LWORK, RWORK, IWORK, INFO )
234 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
238 REAL RWORK( * ), S( * )
239 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
247 parameter( czero = ( 0.0e+0, 0.0e+0 ),
248 $ cone = ( 1.0e+0, 0.0e+0 ) )
250 parameter( zero = 0.0e+0, one = 1.0e+0 )
253 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
254 INTEGER BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
255 $ iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
256 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
257 $ mnthr1, mnthr2, nrwork, nwork, wrkbl
258 INTEGER LWORK_CGEBRD_MN, LWORK_CGEBRD_MM,
259 $ lwork_cgebrd_nn, lwork_cgelqf_mn,
261 $ lwork_cungbr_p_mn, lwork_cungbr_p_nn,
262 $ lwork_cungbr_q_mn, lwork_cungbr_q_mm,
263 $ lwork_cunglq_mn, lwork_cunglq_nn,
264 $ lwork_cungqr_mm, lwork_cungqr_mn,
265 $ lwork_cunmbr_prc_mm, lwork_cunmbr_qln_mm,
266 $ lwork_cunmbr_prc_mn, lwork_cunmbr_qln_mn,
267 $ lwork_cunmbr_prc_nn, lwork_cunmbr_qln_nn
268 REAL ANRM, BIGNUM, EPS, SMLNUM
281 LOGICAL LSAME, SISNAN
283 EXTERNAL lsame, slamch, clange, sisnan
286 INTRINSIC int, max, min, sqrt
294 mnthr1 = int( minmn*17.0e0 / 9.0e0 )
295 mnthr2 = int( minmn*5.0e0 / 3.0e0 )
296 wntqa = lsame( jobz,
'A' )
297 wntqs = lsame( jobz,
'S' )
298 wntqas = wntqa .OR. wntqs
299 wntqo = lsame( jobz,
'O' )
300 wntqn = lsame( jobz,
'N' )
301 lquery = ( lwork.EQ.-1 )
305 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
307 ELSE IF( m.LT.0 )
THEN
309 ELSE IF( n.LT.0 )
THEN
311 ELSE IF( lda.LT.max( 1, m ) )
THEN
313 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
314 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
316 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
317 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
318 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
333 IF( m.GE.n .AND. minmn.GT.0 )
THEN
342 CALL cgebrd( m, n, cdum(1), m, dum(1), dum(1), cdum(1),
343 $ cdum(1), cdum(1), -1, ierr )
344 lwork_cgebrd_mn = int( cdum(1) )
346 CALL cgebrd( n, n, cdum(1), n, dum(1), dum(1), cdum(1),
347 $ cdum(1), cdum(1), -1, ierr )
348 lwork_cgebrd_nn = int( cdum(1) )
350 CALL cgeqrf( m, n, cdum(1), m, cdum(1), cdum(1), -1, ierr )
351 lwork_cgeqrf_mn = int( cdum(1) )
353 CALL cungbr(
'P', n, n, n, cdum(1), n, cdum(1), cdum(1),
355 lwork_cungbr_p_nn = int( cdum(1) )
357 CALL cungbr(
'Q', m, m, n, cdum(1), m, cdum(1), cdum(1),
359 lwork_cungbr_q_mm = int( cdum(1) )
361 CALL cungbr(
'Q', m, n, n, cdum(1), m, cdum(1), cdum(1),
363 lwork_cungbr_q_mn = int( cdum(1) )
365 CALL cungqr( m, m, n, cdum(1), m, cdum(1), cdum(1),
367 lwork_cungqr_mm = int( cdum(1) )
369 CALL cungqr( m, n, n, cdum(1), m, cdum(1), cdum(1),
371 lwork_cungqr_mn = int( cdum(1) )
373 CALL cunmbr(
'P',
'R',
'C', n, n, n, cdum(1), n, cdum(1),
374 $ cdum(1), n, cdum(1), -1, ierr )
375 lwork_cunmbr_prc_nn = int( cdum(1) )
377 CALL cunmbr(
'Q',
'L',
'N', m, m, n, cdum(1), m, cdum(1),
378 $ cdum(1), m, cdum(1), -1, ierr )
379 lwork_cunmbr_qln_mm = int( cdum(1) )
381 CALL cunmbr(
'Q',
'L',
'N', m, n, n, cdum(1), m, cdum(1),
382 $ cdum(1), m, cdum(1), -1, ierr )
383 lwork_cunmbr_qln_mn = int( cdum(1) )
385 CALL cunmbr(
'Q',
'L',
'N', n, n, n, cdum(1), n, cdum(1),
386 $ cdum(1), n, cdum(1), -1, ierr )
387 lwork_cunmbr_qln_nn = int( cdum(1) )
389 IF( m.GE.mnthr1 )
THEN
394 maxwrk = n + lwork_cgeqrf_mn
395 maxwrk = max( maxwrk, 2*n + lwork_cgebrd_nn )
397 ELSE IF( wntqo )
THEN
401 wrkbl = n + lwork_cgeqrf_mn
402 wrkbl = max( wrkbl, n + lwork_cungqr_mn )
403 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
404 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
405 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
406 maxwrk = m*n + n*n + wrkbl
408 ELSE IF( wntqs )
THEN
412 wrkbl = n + lwork_cgeqrf_mn
413 wrkbl = max( wrkbl, n + lwork_cungqr_mn )
414 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
415 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
416 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
419 ELSE IF( wntqa )
THEN
423 wrkbl = n + lwork_cgeqrf_mn
424 wrkbl = max( wrkbl, n + lwork_cungqr_mm )
425 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
426 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
427 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
429 minwrk = n*n + max( 3*n, n + m )
431 ELSE IF( m.GE.mnthr2 )
THEN
435 maxwrk = 2*n + lwork_cgebrd_mn
439 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
440 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mn )
441 maxwrk = maxwrk + m*n
442 minwrk = minwrk + n*n
443 ELSE IF( wntqs )
THEN
445 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
446 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mn )
447 ELSE IF( wntqa )
THEN
449 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
450 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mm )
456 maxwrk = 2*n + lwork_cgebrd_mn
460 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
461 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mn )
462 maxwrk = maxwrk + m*n
463 minwrk = minwrk + n*n
464 ELSE IF( wntqs )
THEN
466 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mn )
467 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
468 ELSE IF( wntqa )
THEN
470 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mm )
471 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
474 ELSE IF( minmn.GT.0 )
THEN
483 CALL cgebrd( m, n, cdum(1), m, dum(1), dum(1), cdum(1),
484 $ cdum(1), cdum(1), -1, ierr )
485 lwork_cgebrd_mn = int( cdum(1) )
487 CALL cgebrd( m, m, cdum(1), m, dum(1), dum(1), cdum(1),
488 $ cdum(1), cdum(1), -1, ierr )
489 lwork_cgebrd_mm = int( cdum(1) )
491 CALL cgelqf( m, n, cdum(1), m, cdum(1), cdum(1), -1, ierr )
492 lwork_cgelqf_mn = int( cdum(1) )
494 CALL cungbr(
'P', m, n, m, cdum(1), m, cdum(1), cdum(1),
496 lwork_cungbr_p_mn = int( cdum(1) )
498 CALL cungbr(
'P', n, n, m, cdum(1), n, cdum(1), cdum(1),
500 lwork_cungbr_p_nn = int( cdum(1) )
502 CALL cungbr(
'Q', m, m, n, cdum(1), m, cdum(1), cdum(1),
504 lwork_cungbr_q_mm = int( cdum(1) )
506 CALL cunglq( m, n, m, cdum(1), m, cdum(1), cdum(1),
508 lwork_cunglq_mn = int( cdum(1) )
510 CALL cunglq( n, n, m, cdum(1), n, cdum(1), cdum(1),
512 lwork_cunglq_nn = int( cdum(1) )
514 CALL cunmbr(
'P',
'R',
'C', m, m, m, cdum(1), m, cdum(1),
515 $ cdum(1), m, cdum(1), -1, ierr )
516 lwork_cunmbr_prc_mm = int( cdum(1) )
518 CALL cunmbr(
'P',
'R',
'C', m, n, m, cdum(1), m, cdum(1),
519 $ cdum(1), m, cdum(1), -1, ierr )
520 lwork_cunmbr_prc_mn = int( cdum(1) )
522 CALL cunmbr(
'P',
'R',
'C', n, n, m, cdum(1), n, cdum(1),
523 $ cdum(1), n, cdum(1), -1, ierr )
524 lwork_cunmbr_prc_nn = int( cdum(1) )
526 CALL cunmbr(
'Q',
'L',
'N', m, m, m, cdum(1), m, cdum(1),
527 $ cdum(1), m, cdum(1), -1, ierr )
528 lwork_cunmbr_qln_mm = int( cdum(1) )
530 IF( n.GE.mnthr1 )
THEN
535 maxwrk = m + lwork_cgelqf_mn
536 maxwrk = max( maxwrk, 2*m + lwork_cgebrd_mm )
538 ELSE IF( wntqo )
THEN
542 wrkbl = m + lwork_cgelqf_mn
543 wrkbl = max( wrkbl, m + lwork_cunglq_mn )
544 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
545 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
546 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
547 maxwrk = m*n + m*m + wrkbl
549 ELSE IF( wntqs )
THEN
553 wrkbl = m + lwork_cgelqf_mn
554 wrkbl = max( wrkbl, m + lwork_cunglq_mn )
555 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
556 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
557 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
560 ELSE IF( wntqa )
THEN
564 wrkbl = m + lwork_cgelqf_mn
565 wrkbl = max( wrkbl, m + lwork_cunglq_nn )
566 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
567 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
568 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
570 minwrk = m*m + max( 3*m, m + n )
572 ELSE IF( n.GE.mnthr2 )
THEN
576 maxwrk = 2*m + lwork_cgebrd_mn
580 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
581 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_mn )
582 maxwrk = maxwrk + m*n
583 minwrk = minwrk + m*m
584 ELSE IF( wntqs )
THEN
586 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
587 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_mn )
588 ELSE IF( wntqa )
THEN
590 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
591 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_nn )
597 maxwrk = 2*m + lwork_cgebrd_mn
601 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
602 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_mn )
603 maxwrk = maxwrk + m*n
604 minwrk = minwrk + m*m
605 ELSE IF( wntqs )
THEN
607 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
608 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_mn )
609 ELSE IF( wntqa )
THEN
611 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
612 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_nn )
616 maxwrk = max( maxwrk, minwrk )
620 IF( lwork.LT.minwrk .AND. .NOT. lquery )
THEN
626 CALL xerbla(
'CGESDD', -info )
628 ELSE IF( lquery )
THEN
634 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
641 smlnum = sqrt( slamch(
'S' ) ) / eps
642 bignum = one / smlnum
646 anrm = clange(
'M', m, n, a, lda, dum )
647 IF( sisnan( anrm ) )
THEN
652 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
654 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
655 ELSE IF( anrm.GT.bignum )
THEN
657 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
666 IF( m.GE.mnthr1 )
THEN
681 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
682 $ lwork-nwork+1, ierr )
686 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
698 CALL cgebrd( n, n, a, lda, s, rwork( ie ), work( itauq ),
699 $ work( itaup ), work( nwork ), lwork-nwork+1,
707 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum,1,dum,1,
708 $ dum, idum, rwork( nrwork ), iwork, info )
710 ELSE IF( wntqo )
THEN
722 IF( lwork .GE. m*n + n*n + 3*n )
THEN
728 ldwrkr = ( lwork - n*n - 3*n ) / n
738 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
739 $ lwork-nwork+1, ierr )
743 CALL clacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
744 CALL claset(
'L', n-1, n-1, czero, czero, work( ir+1 ),
752 CALL cungqr( m, n, n, a, lda, work( itau ),
753 $ work( nwork ), lwork-nwork+1, ierr )
764 CALL cgebrd( n, n, work( ir ), ldwrkr, s, rwork( ie ),
765 $ work( itauq ), work( itaup ), work( nwork ),
766 $ lwork-nwork+1, ierr )
777 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
778 $ n, rwork( irvt ), n, dum, idum,
779 $ rwork( nrwork ), iwork, info )
787 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
789 CALL cunmbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
790 $ work( itauq ), work( iu ), ldwrku,
791 $ work( nwork ), lwork-nwork+1, ierr )
799 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
800 CALL cunmbr(
'P',
'R',
'C', n, n, n, work( ir ), ldwrkr,
801 $ work( itaup ), vt, ldvt, work( nwork ),
802 $ lwork-nwork+1, ierr )
810 DO 10 i = 1, m, ldwrkr
811 chunk = min( m-i+1, ldwrkr )
812 CALL cgemm(
'N',
'N', chunk, n, n, cone, a( i, 1 ),
813 $ lda, work( iu ), ldwrku, czero,
814 $ work( ir ), ldwrkr )
815 CALL clacpy(
'F', chunk, n, work( ir ), ldwrkr,
819 ELSE IF( wntqs )
THEN
838 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
839 $ lwork-nwork+1, ierr )
843 CALL clacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
844 CALL claset(
'L', n-1, n-1, czero, czero, work( ir+1 ),
852 CALL cungqr( m, n, n, a, lda, work( itau ),
853 $ work( nwork ), lwork-nwork+1, ierr )
864 CALL cgebrd( n, n, work( ir ), ldwrkr, s, rwork( ie ),
865 $ work( itauq ), work( itaup ), work( nwork ),
866 $ lwork-nwork+1, ierr )
877 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
878 $ n, rwork( irvt ), n, dum, idum,
879 $ rwork( nrwork ), iwork, info )
887 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
888 CALL cunmbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
889 $ work( itauq ), u, ldu, work( nwork ),
890 $ lwork-nwork+1, ierr )
898 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
899 CALL cunmbr(
'P',
'R',
'C', n, n, n, work( ir ), ldwrkr,
900 $ work( itaup ), vt, ldvt, work( nwork ),
901 $ lwork-nwork+1, ierr )
908 CALL clacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
909 CALL cgemm(
'N',
'N', m, n, n, cone, a, lda, work( ir ),
910 $ ldwrkr, czero, u, ldu )
912 ELSE IF( wntqa )
THEN
931 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
932 $ lwork-nwork+1, ierr )
933 CALL clacpy(
'L', m, n, a, lda, u, ldu )
940 CALL cungqr( m, m, n, u, ldu, work( itau ),
941 $ work( nwork ), lwork-nwork+1, ierr )
945 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
957 CALL cgebrd( n, n, a, lda, s, rwork( ie ), work( itauq ),
958 $ work( itaup ), work( nwork ), lwork-nwork+1,
970 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
971 $ n, rwork( irvt ), n, dum, idum,
972 $ rwork( nrwork ), iwork, info )
980 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
982 CALL cunmbr(
'Q',
'L',
'N', n, n, n, a, lda,
983 $ work( itauq ), work( iu ), ldwrku,
984 $ work( nwork ), lwork-nwork+1, ierr )
992 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
993 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
994 $ work( itaup ), vt, ldvt, work( nwork ),
995 $ lwork-nwork+1, ierr )
1002 CALL cgemm(
'N',
'N', m, n, n, cone, u, ldu, work( iu ),
1003 $ ldwrku, czero, a, lda )
1007 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1011 ELSE IF( m.GE.mnthr2 )
THEN
1030 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1031 $ work( itaup ), work( nwork ), lwork-nwork+1,
1040 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum, 1,dum,1,
1041 $ dum, idum, rwork( nrwork ), iwork, info )
1042 ELSE IF( wntqo )
THEN
1054 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1055 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1056 $ work( nwork ), lwork-nwork+1, ierr )
1063 CALL cungbr(
'Q', m, n, n, a, lda, work( itauq ),
1064 $ work( nwork ), lwork-nwork+1, ierr )
1066 IF( lwork .GE. m*n + 3*n )
THEN
1075 ldwrku = ( lwork - 3*n ) / n
1077 nwork = iu + ldwrku*n
1085 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1086 $ n, rwork( irvt ), n, dum, idum,
1087 $ rwork( nrwork ), iwork, info )
1094 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt,
1095 $ work( iu ), ldwrku, rwork( nrwork ) )
1096 CALL clacpy(
'F', n, n, work( iu ), ldwrku, vt, ldvt )
1106 DO 20 i = 1, m, ldwrku
1107 chunk = min( m-i+1, ldwrku )
1108 CALL clacrm( chunk, n, a( i, 1 ), lda, rwork( iru ),
1109 $ n, work( iu ), ldwrku, rwork( nrwork ) )
1110 CALL clacpy(
'F', chunk, n, work( iu ), ldwrku,
1114 ELSE IF( wntqs )
THEN
1122 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1123 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1124 $ work( nwork ), lwork-nwork+1, ierr )
1131 CALL clacpy(
'L', m, n, a, lda, u, ldu )
1132 CALL cungbr(
'Q', m, n, n, u, ldu, work( itauq ),
1133 $ work( nwork ), lwork-nwork+1, ierr )
1144 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1145 $ n, rwork( irvt ), n, dum, idum,
1146 $ rwork( nrwork ), iwork, info )
1153 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt, a, lda,
1155 CALL clacpy(
'F', n, n, a, lda, vt, ldvt )
1163 CALL clacrm( m, n, u, ldu, rwork( iru ), n, a, lda,
1165 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1174 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1175 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1176 $ work( nwork ), lwork-nwork+1, ierr )
1183 CALL clacpy(
'L', m, n, a, lda, u, ldu )
1184 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1185 $ work( nwork ), lwork-nwork+1, ierr )
1196 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1197 $ n, rwork( irvt ), n, dum, idum,
1198 $ rwork( nrwork ), iwork, info )
1205 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt, a, lda,
1207 CALL clacpy(
'F', n, n, a, lda, vt, ldvt )
1215 CALL clacrm( m, n, u, ldu, rwork( iru ), n, a, lda,
1217 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1239 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1240 $ work( itaup ), work( nwork ), lwork-nwork+1,
1249 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum,1,dum,1,
1250 $ dum, idum, rwork( nrwork ), iwork, info )
1251 ELSE IF( wntqo )
THEN
1256 IF( lwork .GE. m*n + 3*n )
THEN
1265 ldwrku = ( lwork - 3*n ) / n
1267 nwork = iu + ldwrku*n
1276 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1277 $ n, rwork( irvt ), n, dum, idum,
1278 $ rwork( nrwork ), iwork, info )
1286 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1287 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1288 $ work( itaup ), vt, ldvt, work( nwork ),
1289 $ lwork-nwork+1, ierr )
1291 IF( lwork .GE. m*n + 3*n )
THEN
1301 CALL claset(
'F', m, n, czero, czero, work( iu ),
1303 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
1305 CALL cunmbr(
'Q',
'L',
'N', m, n, n, a, lda,
1306 $ work( itauq ), work( iu ), ldwrku,
1307 $ work( nwork ), lwork-nwork+1, ierr )
1308 CALL clacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
1317 CALL cungbr(
'Q', m, n, n, a, lda, work( itauq ),
1318 $ work( nwork ), lwork-nwork+1, ierr )
1328 DO 30 i = 1, m, ldwrku
1329 chunk = min( m-i+1, ldwrku )
1330 CALL clacrm( chunk, n, a( i, 1 ), lda,
1331 $ rwork( iru ), n, work( iu ), ldwrku,
1333 CALL clacpy(
'F', chunk, n, work( iu ), ldwrku,
1338 ELSE IF( wntqs )
THEN
1350 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1351 $ n, rwork( irvt ), n, dum, idum,
1352 $ rwork( nrwork ), iwork, info )
1360 CALL claset(
'F', m, n, czero, czero, u, ldu )
1361 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
1362 CALL cunmbr(
'Q',
'L',
'N', m, n, n, a, lda,
1363 $ work( itauq ), u, ldu, work( nwork ),
1364 $ lwork-nwork+1, ierr )
1372 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1373 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1374 $ work( itaup ), vt, ldvt, work( nwork ),
1375 $ lwork-nwork+1, ierr )
1388 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1389 $ n, rwork( irvt ), n, dum, idum,
1390 $ rwork( nrwork ), iwork, info )
1394 CALL claset(
'F', m, m, czero, czero, u, ldu )
1396 CALL claset(
'F', m-n, m-n, czero, cone,
1397 $ u( n+1, n+1 ), ldu )
1406 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
1407 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
1408 $ work( itauq ), u, ldu, work( nwork ),
1409 $ lwork-nwork+1, ierr )
1417 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1418 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1419 $ work( itaup ), vt, ldvt, work( nwork ),
1420 $ lwork-nwork+1, ierr )
1431 IF( n.GE.mnthr1 )
THEN
1446 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1447 $ lwork-nwork+1, ierr )
1451 CALL claset(
'U', m-1, m-1, czero, czero, a( 1, 2 ),
1463 CALL cgebrd( m, m, a, lda, s, rwork( ie ), work( itauq ),
1464 $ work( itaup ), work( nwork ), lwork-nwork+1,
1472 CALL sbdsdc(
'U',
'N', m, s, rwork( ie ), dum,1,dum,1,
1473 $ dum, idum, rwork( nrwork ), iwork, info )
1475 ELSE IF( wntqo )
THEN
1487 IF( lwork .GE. m*n + m*m + 3*m )
THEN
1498 chunk = ( lwork - m*m - 3*m ) / m
1500 itau = il + ldwrkl*chunk
1508 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1509 $ lwork-nwork+1, ierr )
1513 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1514 CALL claset(
'U', m-1, m-1, czero, czero,
1515 $ work( il+ldwrkl ), ldwrkl )
1522 CALL cunglq( m, n, m, a, lda, work( itau ),
1523 $ work( nwork ), lwork-nwork+1, ierr )
1534 CALL cgebrd( m, m, work( il ), ldwrkl, s, rwork( ie ),
1535 $ work( itauq ), work( itaup ), work( nwork ),
1536 $ lwork-nwork+1, ierr )
1547 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1548 $ m, rwork( irvt ), m, dum, idum,
1549 $ rwork( nrwork ), iwork, info )
1557 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1558 CALL cunmbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1559 $ work( itauq ), u, ldu, work( nwork ),
1560 $ lwork-nwork+1, ierr )
1568 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
1570 CALL cunmbr(
'P',
'R',
'C', m, m, m, work( il ), ldwrkl,
1571 $ work( itaup ), work( ivt ), ldwkvt,
1572 $ work( nwork ), lwork-nwork+1, ierr )
1580 DO 40 i = 1, n, chunk
1581 blk = min( n-i+1, chunk )
1582 CALL cgemm(
'N',
'N', m, blk, m, cone, work( ivt ), m,
1583 $ a( 1, i ), lda, czero, work( il ),
1585 CALL clacpy(
'F', m, blk, work( il ), ldwrkl,
1589 ELSE IF( wntqs )
THEN
1600 itau = il + ldwrkl*m
1608 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1609 $ lwork-nwork+1, ierr )
1613 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1614 CALL claset(
'U', m-1, m-1, czero, czero,
1615 $ work( il+ldwrkl ), ldwrkl )
1622 CALL cunglq( m, n, m, a, lda, work( itau ),
1623 $ work( nwork ), lwork-nwork+1, ierr )
1634 CALL cgebrd( m, m, work( il ), ldwrkl, s, rwork( ie ),
1635 $ work( itauq ), work( itaup ), work( nwork ),
1636 $ lwork-nwork+1, ierr )
1647 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1648 $ m, rwork( irvt ), m, dum, idum,
1649 $ rwork( nrwork ), iwork, info )
1657 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1658 CALL cunmbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1659 $ work( itauq ), u, ldu, work( nwork ),
1660 $ lwork-nwork+1, ierr )
1668 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
1669 CALL cunmbr(
'P',
'R',
'C', m, m, m, work( il ), ldwrkl,
1670 $ work( itaup ), vt, ldvt, work( nwork ),
1671 $ lwork-nwork+1, ierr )
1678 CALL clacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1679 CALL cgemm(
'N',
'N', m, n, m, cone, work( il ), ldwrkl,
1680 $ a, lda, czero, vt, ldvt )
1682 ELSE IF( wntqa )
THEN
1693 itau = ivt + ldwkvt*m
1701 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1702 $ lwork-nwork+1, ierr )
1703 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1710 CALL cunglq( n, n, m, vt, ldvt, work( itau ),
1711 $ work( nwork ), lwork-nwork+1, ierr )
1715 CALL claset(
'U', m-1, m-1, czero, czero, a( 1, 2 ),
1727 CALL cgebrd( m, m, a, lda, s, rwork( ie ), work( itauq ),
1728 $ work( itaup ), work( nwork ), lwork-nwork+1,
1740 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1741 $ m, rwork( irvt ), m, dum, idum,
1742 $ rwork( nrwork ), iwork, info )
1750 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1751 CALL cunmbr(
'Q',
'L',
'N', m, m, m, a, lda,
1752 $ work( itauq ), u, ldu, work( nwork ),
1753 $ lwork-nwork+1, ierr )
1761 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
1763 CALL cunmbr(
'P',
'R',
'C', m, m, m, a, lda,
1764 $ work( itaup ), work( ivt ), ldwkvt,
1765 $ work( nwork ), lwork-nwork+1, ierr )
1772 CALL cgemm(
'N',
'N', m, n, m, cone, work( ivt ), ldwkvt,
1773 $ vt, ldvt, czero, a, lda )
1777 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1781 ELSE IF( n.GE.mnthr2 )
THEN
1800 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1801 $ work( itaup ), work( nwork ), lwork-nwork+1,
1811 CALL sbdsdc(
'L',
'N', m, s, rwork( ie ), dum,1,dum,1,
1812 $ dum, idum, rwork( nrwork ), iwork, info )
1813 ELSE IF( wntqo )
THEN
1825 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1826 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1827 $ work( nwork ), lwork-nwork+1, ierr )
1834 CALL cungbr(
'P', m, n, m, a, lda, work( itaup ),
1835 $ work( nwork ), lwork-nwork+1, ierr )
1838 IF( lwork .GE. m*n + 3*m )
THEN
1842 nwork = ivt + ldwkvt*n
1848 chunk = ( lwork - 3*m ) / m
1849 nwork = ivt + ldwkvt*chunk
1858 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1859 $ m, rwork( irvt ), m, dum, idum,
1860 $ rwork( nrwork ), iwork, info )
1867 CALL clacrm( m, m, u, ldu, rwork( iru ), m, work( ivt ),
1868 $ ldwkvt, rwork( nrwork ) )
1869 CALL clacpy(
'F', m, m, work( ivt ), ldwkvt, u, ldu )
1879 DO 50 i = 1, n, chunk
1880 blk = min( n-i+1, chunk )
1881 CALL clarcm( m, blk, rwork( irvt ), m, a( 1, i ), lda,
1882 $ work( ivt ), ldwkvt, rwork( nrwork ) )
1883 CALL clacpy(
'F', m, blk, work( ivt ), ldwkvt,
1886 ELSE IF( wntqs )
THEN
1894 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1895 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1896 $ work( nwork ), lwork-nwork+1, ierr )
1903 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1904 CALL cungbr(
'P', m, n, m, vt, ldvt, work( itaup ),
1905 $ work( nwork ), lwork-nwork+1, ierr )
1916 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1917 $ m, rwork( irvt ), m, dum, idum,
1918 $ rwork( nrwork ), iwork, info )
1925 CALL clacrm( m, m, u, ldu, rwork( iru ), m, a, lda,
1927 CALL clacpy(
'F', m, m, a, lda, u, ldu )
1935 CALL clarcm( m, n, rwork( irvt ), m, vt, ldvt, a, lda,
1937 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1946 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1947 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1948 $ work( nwork ), lwork-nwork+1, ierr )
1955 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1956 CALL cungbr(
'P', n, n, m, vt, ldvt, work( itaup ),
1957 $ work( nwork ), lwork-nwork+1, ierr )
1968 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1969 $ m, rwork( irvt ), m, dum, idum,
1970 $ rwork( nrwork ), iwork, info )
1977 CALL clacrm( m, m, u, ldu, rwork( iru ), m, a, lda,
1979 CALL clacpy(
'F', m, m, a, lda, u, ldu )
1987 CALL clarcm( m, n, rwork( irvt ), m, vt, ldvt, a, lda,
1989 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
2011 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
2012 $ work( itaup ), work( nwork ), lwork-nwork+1,
2021 CALL sbdsdc(
'L',
'N', m, s, rwork( ie ), dum,1,dum,1,
2022 $ dum, idum, rwork( nrwork ), iwork, info )
2023 ELSE IF( wntqo )
THEN
2027 IF( lwork .GE. m*n + 3*m )
THEN
2031 CALL claset(
'F', m, n, czero, czero, work( ivt ),
2033 nwork = ivt + ldwkvt*n
2038 chunk = ( lwork - 3*m ) / m
2039 nwork = ivt + ldwkvt*chunk
2051 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2052 $ m, rwork( irvt ), m, dum, idum,
2053 $ rwork( nrwork ), iwork, info )
2061 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2062 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2063 $ work( itauq ), u, ldu, work( nwork ),
2064 $ lwork-nwork+1, ierr )
2066 IF( lwork .GE. m*n + 3*m )
THEN
2076 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
2078 CALL cunmbr(
'P',
'R',
'C', m, n, m, a, lda,
2079 $ work( itaup ), work( ivt ), ldwkvt,
2080 $ work( nwork ), lwork-nwork+1, ierr )
2081 CALL clacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
2090 CALL cungbr(
'P', m, n, m, a, lda, work( itaup ),
2091 $ work( nwork ), lwork-nwork+1, ierr )
2101 DO 60 i = 1, n, chunk
2102 blk = min( n-i+1, chunk )
2103 CALL clarcm( m, blk, rwork( irvt ), m, a( 1, i ),
2104 $ lda, work( ivt ), ldwkvt,
2106 CALL clacpy(
'F', m, blk, work( ivt ), ldwkvt,
2110 ELSE IF( wntqs )
THEN
2122 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2123 $ m, rwork( irvt ), m, dum, idum,
2124 $ rwork( nrwork ), iwork, info )
2132 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2133 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2134 $ work( itauq ), u, ldu, work( nwork ),
2135 $ lwork-nwork+1, ierr )
2143 CALL claset(
'F', m, n, czero, czero, vt, ldvt )
2144 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
2145 CALL cunmbr(
'P',
'R',
'C', m, n, m, a, lda,
2146 $ work( itaup ), vt, ldvt, work( nwork ),
2147 $ lwork-nwork+1, ierr )
2161 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2162 $ m, rwork( irvt ), m, dum, idum,
2163 $ rwork( nrwork ), iwork, info )
2171 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2172 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2173 $ work( itauq ), u, ldu, work( nwork ),
2174 $ lwork-nwork+1, ierr )
2178 CALL claset(
'F', n, n, czero, cone, vt, ldvt )
2186 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
2187 CALL cunmbr(
'P',
'R',
'C', n, n, m, a, lda,
2188 $ work( itaup ), vt, ldvt, work( nwork ),
2189 $ lwork-nwork+1, ierr )
2198 IF( iscl.EQ.1 )
THEN
2199 IF( anrm.GT.bignum )
2200 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
2202 IF( info.NE.0 .AND. anrm.GT.bignum )
2203 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn-1, 1,
2204 $ rwork( ie ), minmn, ierr )
2205 IF( anrm.LT.smlnum )
2206 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
2208 IF( info.NE.0 .AND. anrm.LT.smlnum )
2209 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn-1, 1,
2210 $ rwork( ie ), minmn, ierr )
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 xerbla(SRNAME, INFO)
XERBLA
subroutine sbdsdc(UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ, WORK, IWORK, INFO)
SBDSDC
subroutine cgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
CGEMM
subroutine cungbr(VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
CUNGBR
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 cgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGELQF
subroutine cgesdd(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, IWORK, INFO)
CGESDD
subroutine clarcm(M, N, A, LDA, B, LDB, C, LDC, RWORK)
CLARCM copies all or part of a real two-dimensional array to a complex array.
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 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 clacrm(M, N, A, LDA, B, LDB, C, LDC, RWORK)
CLACRM multiplies a complex matrix by a square real matrix.
subroutine clacp2(UPLO, M, N, A, LDA, B, LDB)
CLACP2 copies all or part of a real two-dimensional array to a complex array.
subroutine clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
subroutine cunglq(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
CUNGLQ
subroutine cunmbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMBR
subroutine cungqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
CUNGQR