225 SUBROUTINE cgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
226 $ WORK, LWORK, RWORK, IWORK, INFO )
235 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
239 REAL RWORK( * ), S( * )
240 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
248 parameter( czero = ( 0.0e+0, 0.0e+0 ),
249 $ cone = ( 1.0e+0, 0.0e+0 ) )
251 parameter( zero = 0.0e+0, one = 1.0e+0 )
254 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
255 INTEGER BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
256 $ iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
257 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
258 $ mnthr1, mnthr2, nrwork, nwork, wrkbl
259 INTEGER LWORK_CGEBRD_MN, LWORK_CGEBRD_MM,
260 $ lwork_cgebrd_nn, lwork_cgelqf_mn,
262 $ lwork_cungbr_p_mn, lwork_cungbr_p_nn,
263 $ lwork_cungbr_q_mn, lwork_cungbr_q_mm,
264 $ lwork_cunglq_mn, lwork_cunglq_nn,
265 $ lwork_cungqr_mm, lwork_cungqr_mn,
266 $ lwork_cunmbr_prc_mm, lwork_cunmbr_qln_mm,
267 $ lwork_cunmbr_prc_mn, lwork_cunmbr_qln_mn,
268 $ lwork_cunmbr_prc_nn, lwork_cunmbr_qln_nn
269 REAL ANRM, BIGNUM, EPS, SMLNUM
282 LOGICAL LSAME, SISNAN
283 REAL SLAMCH, CLANGE, SROUNDUP_LWORK
284 EXTERNAL lsame, slamch, clange, sisnan,
288 INTRINSIC int, max, min, sqrt
296 mnthr1 = int( minmn*17.0e0 / 9.0e0 )
297 mnthr2 = int( minmn*5.0e0 / 3.0e0 )
298 wntqa = lsame( jobz,
'A' )
299 wntqs = lsame( jobz,
'S' )
300 wntqas = wntqa .OR. wntqs
301 wntqo = lsame( jobz,
'O' )
302 wntqn = lsame( jobz,
'N' )
303 lquery = ( lwork.EQ.-1 )
307 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
309 ELSE IF( m.LT.0 )
THEN
311 ELSE IF( n.LT.0 )
THEN
313 ELSE IF( lda.LT.max( 1, m ) )
THEN
315 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
316 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
318 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
319 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
320 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
335 IF( m.GE.n .AND. minmn.GT.0 )
THEN
344 CALL cgebrd( m, n, cdum(1), m, dum(1), dum(1), cdum(1),
345 $ cdum(1), cdum(1), -1, ierr )
346 lwork_cgebrd_mn = int( cdum(1) )
348 CALL cgebrd( n, n, cdum(1), n, dum(1), dum(1), cdum(1),
349 $ cdum(1), cdum(1), -1, ierr )
350 lwork_cgebrd_nn = int( cdum(1) )
352 CALL cgeqrf( m, n, cdum(1), m, cdum(1), cdum(1), -1, ierr )
353 lwork_cgeqrf_mn = int( cdum(1) )
355 CALL cungbr(
'P', n, n, n, cdum(1), n, cdum(1), cdum(1),
357 lwork_cungbr_p_nn = int( cdum(1) )
359 CALL cungbr(
'Q', m, m, n, cdum(1), m, cdum(1), cdum(1),
361 lwork_cungbr_q_mm = int( cdum(1) )
363 CALL cungbr(
'Q', m, n, n, cdum(1), m, cdum(1), cdum(1),
365 lwork_cungbr_q_mn = int( cdum(1) )
367 CALL cungqr( m, m, n, cdum(1), m, cdum(1), cdum(1),
369 lwork_cungqr_mm = int( cdum(1) )
371 CALL cungqr( m, n, n, cdum(1), m, cdum(1), cdum(1),
373 lwork_cungqr_mn = int( cdum(1) )
375 CALL cunmbr(
'P',
'R',
'C', n, n, n, cdum(1), n, cdum(1),
376 $ cdum(1), n, cdum(1), -1, ierr )
377 lwork_cunmbr_prc_nn = int( cdum(1) )
379 CALL cunmbr(
'Q',
'L',
'N', m, m, n, cdum(1), m, cdum(1),
380 $ cdum(1), m, cdum(1), -1, ierr )
381 lwork_cunmbr_qln_mm = int( cdum(1) )
383 CALL cunmbr(
'Q',
'L',
'N', m, n, n, cdum(1), m, cdum(1),
384 $ cdum(1), m, cdum(1), -1, ierr )
385 lwork_cunmbr_qln_mn = int( cdum(1) )
387 CALL cunmbr(
'Q',
'L',
'N', n, n, n, cdum(1), n, cdum(1),
388 $ cdum(1), n, cdum(1), -1, ierr )
389 lwork_cunmbr_qln_nn = int( cdum(1) )
391 IF( m.GE.mnthr1 )
THEN
396 maxwrk = n + lwork_cgeqrf_mn
397 maxwrk = max( maxwrk, 2*n + lwork_cgebrd_nn )
399 ELSE IF( wntqo )
THEN
403 wrkbl = n + lwork_cgeqrf_mn
404 wrkbl = max( wrkbl, n + lwork_cungqr_mn )
405 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
406 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
407 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
408 maxwrk = m*n + n*n + wrkbl
410 ELSE IF( wntqs )
THEN
414 wrkbl = n + lwork_cgeqrf_mn
415 wrkbl = max( wrkbl, n + lwork_cungqr_mn )
416 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
417 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
418 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
421 ELSE IF( wntqa )
THEN
425 wrkbl = n + lwork_cgeqrf_mn
426 wrkbl = max( wrkbl, n + lwork_cungqr_mm )
427 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
428 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
429 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
431 minwrk = n*n + max( 3*n, n + m )
433 ELSE IF( m.GE.mnthr2 )
THEN
437 maxwrk = 2*n + lwork_cgebrd_mn
441 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
442 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mn )
443 maxwrk = maxwrk + m*n
444 minwrk = minwrk + n*n
445 ELSE IF( wntqs )
THEN
447 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
448 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mn )
449 ELSE IF( wntqa )
THEN
451 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
452 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mm )
458 maxwrk = 2*n + lwork_cgebrd_mn
462 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
463 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mn )
464 maxwrk = maxwrk + m*n
465 minwrk = minwrk + n*n
466 ELSE IF( wntqs )
THEN
468 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mn )
469 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
470 ELSE IF( wntqa )
THEN
472 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mm )
473 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
476 ELSE IF( minmn.GT.0 )
THEN
485 CALL cgebrd( m, n, cdum(1), m, dum(1), dum(1), cdum(1),
486 $ cdum(1), cdum(1), -1, ierr )
487 lwork_cgebrd_mn = int( cdum(1) )
489 CALL cgebrd( m, m, cdum(1), m, dum(1), dum(1), cdum(1),
490 $ cdum(1), cdum(1), -1, ierr )
491 lwork_cgebrd_mm = int( cdum(1) )
493 CALL cgelqf( m, n, cdum(1), m, cdum(1), cdum(1), -1, ierr )
494 lwork_cgelqf_mn = int( cdum(1) )
496 CALL cungbr(
'P', m, n, m, cdum(1), m, cdum(1), cdum(1),
498 lwork_cungbr_p_mn = int( cdum(1) )
500 CALL cungbr(
'P', n, n, m, cdum(1), n, cdum(1), cdum(1),
502 lwork_cungbr_p_nn = int( cdum(1) )
504 CALL cungbr(
'Q', m, m, n, cdum(1), m, cdum(1), cdum(1),
506 lwork_cungbr_q_mm = int( cdum(1) )
508 CALL cunglq( m, n, m, cdum(1), m, cdum(1), cdum(1),
510 lwork_cunglq_mn = int( cdum(1) )
512 CALL cunglq( n, n, m, cdum(1), n, cdum(1), cdum(1),
514 lwork_cunglq_nn = int( cdum(1) )
516 CALL cunmbr(
'P',
'R',
'C', m, m, m, cdum(1), m, cdum(1),
517 $ cdum(1), m, cdum(1), -1, ierr )
518 lwork_cunmbr_prc_mm = int( cdum(1) )
520 CALL cunmbr(
'P',
'R',
'C', m, n, m, cdum(1), m, cdum(1),
521 $ cdum(1), m, cdum(1), -1, ierr )
522 lwork_cunmbr_prc_mn = int( cdum(1) )
524 CALL cunmbr(
'P',
'R',
'C', n, n, m, cdum(1), n, cdum(1),
525 $ cdum(1), n, cdum(1), -1, ierr )
526 lwork_cunmbr_prc_nn = int( cdum(1) )
528 CALL cunmbr(
'Q',
'L',
'N', m, m, m, cdum(1), m, cdum(1),
529 $ cdum(1), m, cdum(1), -1, ierr )
530 lwork_cunmbr_qln_mm = int( cdum(1) )
532 IF( n.GE.mnthr1 )
THEN
537 maxwrk = m + lwork_cgelqf_mn
538 maxwrk = max( maxwrk, 2*m + lwork_cgebrd_mm )
540 ELSE IF( wntqo )
THEN
544 wrkbl = m + lwork_cgelqf_mn
545 wrkbl = max( wrkbl, m + lwork_cunglq_mn )
546 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
547 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
548 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
549 maxwrk = m*n + m*m + wrkbl
551 ELSE IF( wntqs )
THEN
555 wrkbl = m + lwork_cgelqf_mn
556 wrkbl = max( wrkbl, m + lwork_cunglq_mn )
557 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
558 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
559 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
562 ELSE IF( wntqa )
THEN
566 wrkbl = m + lwork_cgelqf_mn
567 wrkbl = max( wrkbl, m + lwork_cunglq_nn )
568 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
569 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
570 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
572 minwrk = m*m + max( 3*m, m + n )
574 ELSE IF( n.GE.mnthr2 )
THEN
578 maxwrk = 2*m + lwork_cgebrd_mn
582 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
583 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_mn )
584 maxwrk = maxwrk + m*n
585 minwrk = minwrk + m*m
586 ELSE IF( wntqs )
THEN
588 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
589 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_mn )
590 ELSE IF( wntqa )
THEN
592 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
593 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_nn )
599 maxwrk = 2*m + lwork_cgebrd_mn
603 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
604 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_mn )
605 maxwrk = maxwrk + m*n
606 minwrk = minwrk + m*m
607 ELSE IF( wntqs )
THEN
609 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
610 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_mn )
611 ELSE IF( wntqa )
THEN
613 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
614 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_nn )
618 maxwrk = max( maxwrk, minwrk )
621 work( 1 ) = sroundup_lwork( maxwrk )
622 IF( lwork.LT.minwrk .AND. .NOT. lquery )
THEN
628 CALL xerbla(
'CGESDD', -info )
630 ELSE IF( lquery )
THEN
636 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
643 smlnum = sqrt( slamch(
'S' ) ) / eps
644 bignum = one / smlnum
648 anrm = clange(
'M', m, n, a, lda, dum )
649 IF( sisnan( anrm ) )
THEN
654 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
656 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
657 ELSE IF( anrm.GT.bignum )
THEN
659 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
668 IF( m.GE.mnthr1 )
THEN
683 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
684 $ lwork-nwork+1, ierr )
688 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
700 CALL cgebrd( n, n, a, lda, s, rwork( ie ), work( itauq ),
701 $ work( itaup ), work( nwork ), lwork-nwork+1,
709 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum,1,dum,1,
710 $ dum, idum, rwork( nrwork ), iwork, info )
712 ELSE IF( wntqo )
THEN
724 IF( lwork .GE. m*n + n*n + 3*n )
THEN
730 ldwrkr = ( lwork - n*n - 3*n ) / n
740 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
741 $ lwork-nwork+1, ierr )
745 CALL clacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
746 CALL claset(
'L', n-1, n-1, czero, czero, work( ir+1 ),
754 CALL cungqr( m, n, n, a, lda, work( itau ),
755 $ work( nwork ), lwork-nwork+1, ierr )
766 CALL cgebrd( n, n, work( ir ), ldwrkr, s, rwork( ie ),
767 $ work( itauq ), work( itaup ), work( nwork ),
768 $ lwork-nwork+1, ierr )
779 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
780 $ n, rwork( irvt ), n, dum, idum,
781 $ rwork( nrwork ), iwork, info )
789 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
791 CALL cunmbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
792 $ work( itauq ), work( iu ), ldwrku,
793 $ work( nwork ), lwork-nwork+1, ierr )
801 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
802 CALL cunmbr(
'P',
'R',
'C', n, n, n, work( ir ), ldwrkr,
803 $ work( itaup ), vt, ldvt, work( nwork ),
804 $ lwork-nwork+1, ierr )
812 DO 10 i = 1, m, ldwrkr
813 chunk = min( m-i+1, ldwrkr )
814 CALL cgemm(
'N',
'N', chunk, n, n, cone, a( i, 1 ),
815 $ lda, work( iu ), ldwrku, czero,
816 $ work( ir ), ldwrkr )
817 CALL clacpy(
'F', chunk, n, work( ir ), ldwrkr,
821 ELSE IF( wntqs )
THEN
840 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
841 $ lwork-nwork+1, ierr )
845 CALL clacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
846 CALL claset(
'L', n-1, n-1, czero, czero, work( ir+1 ),
854 CALL cungqr( m, n, n, a, lda, work( itau ),
855 $ work( nwork ), lwork-nwork+1, ierr )
866 CALL cgebrd( n, n, work( ir ), ldwrkr, s, rwork( ie ),
867 $ work( itauq ), work( itaup ), work( nwork ),
868 $ lwork-nwork+1, ierr )
879 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
880 $ n, rwork( irvt ), n, dum, idum,
881 $ rwork( nrwork ), iwork, info )
889 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
890 CALL cunmbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
891 $ work( itauq ), u, ldu, work( nwork ),
892 $ lwork-nwork+1, ierr )
900 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
901 CALL cunmbr(
'P',
'R',
'C', n, n, n, work( ir ), ldwrkr,
902 $ work( itaup ), vt, ldvt, work( nwork ),
903 $ lwork-nwork+1, ierr )
910 CALL clacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
911 CALL cgemm(
'N',
'N', m, n, n, cone, a, lda, work( ir ),
912 $ ldwrkr, czero, u, ldu )
914 ELSE IF( wntqa )
THEN
933 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
934 $ lwork-nwork+1, ierr )
935 CALL clacpy(
'L', m, n, a, lda, u, ldu )
942 CALL cungqr( m, m, n, u, ldu, work( itau ),
943 $ work( nwork ), lwork-nwork+1, ierr )
947 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
959 CALL cgebrd( n, n, a, lda, s, rwork( ie ), work( itauq ),
960 $ work( itaup ), work( nwork ), lwork-nwork+1,
972 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
973 $ n, rwork( irvt ), n, dum, idum,
974 $ rwork( nrwork ), iwork, info )
982 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
984 CALL cunmbr(
'Q',
'L',
'N', n, n, n, a, lda,
985 $ work( itauq ), work( iu ), ldwrku,
986 $ work( nwork ), lwork-nwork+1, ierr )
994 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
995 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
996 $ work( itaup ), vt, ldvt, work( nwork ),
997 $ lwork-nwork+1, ierr )
1004 CALL cgemm(
'N',
'N', m, n, n, cone, u, ldu, work( iu ),
1005 $ ldwrku, czero, a, lda )
1009 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1013 ELSE IF( m.GE.mnthr2 )
THEN
1032 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1033 $ work( itaup ), work( nwork ), lwork-nwork+1,
1042 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum, 1,dum,1,
1043 $ dum, idum, rwork( nrwork ), iwork, info )
1044 ELSE IF( wntqo )
THEN
1056 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1057 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1058 $ work( nwork ), lwork-nwork+1, ierr )
1065 CALL cungbr(
'Q', m, n, n, a, lda, work( itauq ),
1066 $ work( nwork ), lwork-nwork+1, ierr )
1068 IF( lwork .GE. m*n + 3*n )
THEN
1077 ldwrku = ( lwork - 3*n ) / n
1079 nwork = iu + ldwrku*n
1087 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1088 $ n, rwork( irvt ), n, dum, idum,
1089 $ rwork( nrwork ), iwork, info )
1096 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt,
1097 $ work( iu ), ldwrku, rwork( nrwork ) )
1098 CALL clacpy(
'F', n, n, work( iu ), ldwrku, vt, ldvt )
1108 DO 20 i = 1, m, ldwrku
1109 chunk = min( m-i+1, ldwrku )
1110 CALL clacrm( chunk, n, a( i, 1 ), lda, rwork( iru ),
1111 $ n, work( iu ), ldwrku, rwork( nrwork ) )
1112 CALL clacpy(
'F', chunk, n, work( iu ), ldwrku,
1116 ELSE IF( wntqs )
THEN
1124 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1125 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1126 $ work( nwork ), lwork-nwork+1, ierr )
1133 CALL clacpy(
'L', m, n, a, lda, u, ldu )
1134 CALL cungbr(
'Q', m, n, n, u, ldu, work( itauq ),
1135 $ work( nwork ), lwork-nwork+1, ierr )
1146 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1147 $ n, rwork( irvt ), n, dum, idum,
1148 $ rwork( nrwork ), iwork, info )
1155 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt, a, lda,
1157 CALL clacpy(
'F', n, n, a, lda, vt, ldvt )
1165 CALL clacrm( m, n, u, ldu, rwork( iru ), n, a, lda,
1167 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1176 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1177 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1178 $ work( nwork ), lwork-nwork+1, ierr )
1185 CALL clacpy(
'L', m, n, a, lda, u, ldu )
1186 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1187 $ work( nwork ), lwork-nwork+1, ierr )
1198 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1199 $ n, rwork( irvt ), n, dum, idum,
1200 $ rwork( nrwork ), iwork, info )
1207 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt, a, lda,
1209 CALL clacpy(
'F', n, n, a, lda, vt, ldvt )
1217 CALL clacrm( m, n, u, ldu, rwork( iru ), n, a, lda,
1219 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1241 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1242 $ work( itaup ), work( nwork ), lwork-nwork+1,
1251 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum,1,dum,1,
1252 $ dum, idum, rwork( nrwork ), iwork, info )
1253 ELSE IF( wntqo )
THEN
1258 IF( lwork .GE. m*n + 3*n )
THEN
1267 ldwrku = ( lwork - 3*n ) / n
1269 nwork = iu + ldwrku*n
1278 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1279 $ n, rwork( irvt ), n, dum, idum,
1280 $ rwork( nrwork ), iwork, info )
1288 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1289 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1290 $ work( itaup ), vt, ldvt, work( nwork ),
1291 $ lwork-nwork+1, ierr )
1293 IF( lwork .GE. m*n + 3*n )
THEN
1303 CALL claset(
'F', m, n, czero, czero, work( iu ),
1305 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
1307 CALL cunmbr(
'Q',
'L',
'N', m, n, n, a, lda,
1308 $ work( itauq ), work( iu ), ldwrku,
1309 $ work( nwork ), lwork-nwork+1, ierr )
1310 CALL clacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
1319 CALL cungbr(
'Q', m, n, n, a, lda, work( itauq ),
1320 $ work( nwork ), lwork-nwork+1, ierr )
1330 DO 30 i = 1, m, ldwrku
1331 chunk = min( m-i+1, ldwrku )
1332 CALL clacrm( chunk, n, a( i, 1 ), lda,
1333 $ rwork( iru ), n, work( iu ), ldwrku,
1335 CALL clacpy(
'F', chunk, n, work( iu ), ldwrku,
1340 ELSE IF( wntqs )
THEN
1352 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1353 $ n, rwork( irvt ), n, dum, idum,
1354 $ rwork( nrwork ), iwork, info )
1362 CALL claset(
'F', m, n, czero, czero, u, ldu )
1363 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
1364 CALL cunmbr(
'Q',
'L',
'N', m, n, n, a, lda,
1365 $ work( itauq ), u, ldu, work( nwork ),
1366 $ lwork-nwork+1, ierr )
1374 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1375 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1376 $ work( itaup ), vt, ldvt, work( nwork ),
1377 $ lwork-nwork+1, ierr )
1390 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1391 $ n, rwork( irvt ), n, dum, idum,
1392 $ rwork( nrwork ), iwork, info )
1396 CALL claset(
'F', m, m, czero, czero, u, ldu )
1398 CALL claset(
'F', m-n, m-n, czero, cone,
1399 $ u( n+1, n+1 ), ldu )
1408 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
1409 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
1410 $ work( itauq ), u, ldu, work( nwork ),
1411 $ lwork-nwork+1, ierr )
1419 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1420 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1421 $ work( itaup ), vt, ldvt, work( nwork ),
1422 $ lwork-nwork+1, ierr )
1433 IF( n.GE.mnthr1 )
THEN
1448 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1449 $ lwork-nwork+1, ierr )
1453 CALL claset(
'U', m-1, m-1, czero, czero, a( 1, 2 ),
1465 CALL cgebrd( m, m, a, lda, s, rwork( ie ), work( itauq ),
1466 $ work( itaup ), work( nwork ), lwork-nwork+1,
1474 CALL sbdsdc(
'U',
'N', m, s, rwork( ie ), dum,1,dum,1,
1475 $ dum, idum, rwork( nrwork ), iwork, info )
1477 ELSE IF( wntqo )
THEN
1489 IF( lwork .GE. m*n + m*m + 3*m )
THEN
1500 chunk = ( lwork - m*m - 3*m ) / m
1502 itau = il + ldwrkl*chunk
1510 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1511 $ lwork-nwork+1, ierr )
1515 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1516 CALL claset(
'U', m-1, m-1, czero, czero,
1517 $ work( il+ldwrkl ), ldwrkl )
1524 CALL cunglq( m, n, m, a, lda, work( itau ),
1525 $ work( nwork ), lwork-nwork+1, ierr )
1536 CALL cgebrd( m, m, work( il ), ldwrkl, s, rwork( ie ),
1537 $ work( itauq ), work( itaup ), work( nwork ),
1538 $ lwork-nwork+1, ierr )
1549 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1550 $ m, rwork( irvt ), m, dum, idum,
1551 $ rwork( nrwork ), iwork, info )
1559 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1560 CALL cunmbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1561 $ work( itauq ), u, ldu, work( nwork ),
1562 $ lwork-nwork+1, ierr )
1570 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
1572 CALL cunmbr(
'P',
'R',
'C', m, m, m, work( il ), ldwrkl,
1573 $ work( itaup ), work( ivt ), ldwkvt,
1574 $ work( nwork ), lwork-nwork+1, ierr )
1582 DO 40 i = 1, n, chunk
1583 blk = min( n-i+1, chunk )
1584 CALL cgemm(
'N',
'N', m, blk, m, cone, work( ivt ), m,
1585 $ a( 1, i ), lda, czero, work( il ),
1587 CALL clacpy(
'F', m, blk, work( il ), ldwrkl,
1591 ELSE IF( wntqs )
THEN
1602 itau = il + ldwrkl*m
1610 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1611 $ lwork-nwork+1, ierr )
1615 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1616 CALL claset(
'U', m-1, m-1, czero, czero,
1617 $ work( il+ldwrkl ), ldwrkl )
1624 CALL cunglq( m, n, m, a, lda, work( itau ),
1625 $ work( nwork ), lwork-nwork+1, ierr )
1636 CALL cgebrd( m, m, work( il ), ldwrkl, s, rwork( ie ),
1637 $ work( itauq ), work( itaup ), work( nwork ),
1638 $ lwork-nwork+1, ierr )
1649 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1650 $ m, rwork( irvt ), m, dum, idum,
1651 $ rwork( nrwork ), iwork, info )
1659 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1660 CALL cunmbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1661 $ work( itauq ), u, ldu, work( nwork ),
1662 $ lwork-nwork+1, ierr )
1670 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
1671 CALL cunmbr(
'P',
'R',
'C', m, m, m, work( il ), ldwrkl,
1672 $ work( itaup ), vt, ldvt, work( nwork ),
1673 $ lwork-nwork+1, ierr )
1680 CALL clacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1681 CALL cgemm(
'N',
'N', m, n, m, cone, work( il ), ldwrkl,
1682 $ a, lda, czero, vt, ldvt )
1684 ELSE IF( wntqa )
THEN
1695 itau = ivt + ldwkvt*m
1703 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1704 $ lwork-nwork+1, ierr )
1705 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1712 CALL cunglq( n, n, m, vt, ldvt, work( itau ),
1713 $ work( nwork ), lwork-nwork+1, ierr )
1717 CALL claset(
'U', m-1, m-1, czero, czero, a( 1, 2 ),
1729 CALL cgebrd( m, m, a, lda, s, rwork( ie ), work( itauq ),
1730 $ work( itaup ), work( nwork ), lwork-nwork+1,
1742 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1743 $ m, rwork( irvt ), m, dum, idum,
1744 $ rwork( nrwork ), iwork, info )
1752 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1753 CALL cunmbr(
'Q',
'L',
'N', m, m, m, a, lda,
1754 $ work( itauq ), u, ldu, work( nwork ),
1755 $ lwork-nwork+1, ierr )
1763 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
1765 CALL cunmbr(
'P',
'R',
'C', m, m, m, a, lda,
1766 $ work( itaup ), work( ivt ), ldwkvt,
1767 $ work( nwork ), lwork-nwork+1, ierr )
1774 CALL cgemm(
'N',
'N', m, n, m, cone, work( ivt ), ldwkvt,
1775 $ vt, ldvt, czero, a, lda )
1779 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1783 ELSE IF( n.GE.mnthr2 )
THEN
1802 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1803 $ work( itaup ), work( nwork ), lwork-nwork+1,
1813 CALL sbdsdc(
'L',
'N', m, s, rwork( ie ), dum,1,dum,1,
1814 $ dum, idum, rwork( nrwork ), iwork, info )
1815 ELSE IF( wntqo )
THEN
1827 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1828 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1829 $ work( nwork ), lwork-nwork+1, ierr )
1836 CALL cungbr(
'P', m, n, m, a, lda, work( itaup ),
1837 $ work( nwork ), lwork-nwork+1, ierr )
1840 IF( lwork .GE. m*n + 3*m )
THEN
1844 nwork = ivt + ldwkvt*n
1850 chunk = ( lwork - 3*m ) / m
1851 nwork = ivt + ldwkvt*chunk
1860 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1861 $ m, rwork( irvt ), m, dum, idum,
1862 $ rwork( nrwork ), iwork, info )
1869 CALL clacrm( m, m, u, ldu, rwork( iru ), m, work( ivt ),
1870 $ ldwkvt, rwork( nrwork ) )
1871 CALL clacpy(
'F', m, m, work( ivt ), ldwkvt, u, ldu )
1881 DO 50 i = 1, n, chunk
1882 blk = min( n-i+1, chunk )
1883 CALL clarcm( m, blk, rwork( irvt ), m, a( 1, i ), lda,
1884 $ work( ivt ), ldwkvt, rwork( nrwork ) )
1885 CALL clacpy(
'F', m, blk, work( ivt ), ldwkvt,
1888 ELSE IF( wntqs )
THEN
1896 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1897 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1898 $ work( nwork ), lwork-nwork+1, ierr )
1905 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1906 CALL cungbr(
'P', m, n, m, vt, ldvt, work( itaup ),
1907 $ work( nwork ), lwork-nwork+1, ierr )
1918 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1919 $ m, rwork( irvt ), m, dum, idum,
1920 $ rwork( nrwork ), iwork, info )
1927 CALL clacrm( m, m, u, ldu, rwork( iru ), m, a, lda,
1929 CALL clacpy(
'F', m, m, a, lda, u, ldu )
1937 CALL clarcm( m, n, rwork( irvt ), m, vt, ldvt, a, lda,
1939 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1948 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1949 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1950 $ work( nwork ), lwork-nwork+1, ierr )
1957 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1958 CALL cungbr(
'P', n, n, m, vt, ldvt, work( itaup ),
1959 $ work( nwork ), lwork-nwork+1, ierr )
1970 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1971 $ m, rwork( irvt ), m, dum, idum,
1972 $ rwork( nrwork ), iwork, info )
1979 CALL clacrm( m, m, u, ldu, rwork( iru ), m, a, lda,
1981 CALL clacpy(
'F', m, m, a, lda, u, ldu )
1989 CALL clarcm( m, n, rwork( irvt ), m, vt, ldvt, a, lda,
1991 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
2013 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
2014 $ work( itaup ), work( nwork ), lwork-nwork+1,
2023 CALL sbdsdc(
'L',
'N', m, s, rwork( ie ), dum,1,dum,1,
2024 $ dum, idum, rwork( nrwork ), iwork, info )
2025 ELSE IF( wntqo )
THEN
2029 IF( lwork .GE. m*n + 3*m )
THEN
2033 CALL claset(
'F', m, n, czero, czero, work( ivt ),
2035 nwork = ivt + ldwkvt*n
2040 chunk = ( lwork - 3*m ) / m
2041 nwork = ivt + ldwkvt*chunk
2053 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2054 $ m, rwork( irvt ), m, dum, idum,
2055 $ rwork( nrwork ), iwork, info )
2063 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2064 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2065 $ work( itauq ), u, ldu, work( nwork ),
2066 $ lwork-nwork+1, ierr )
2068 IF( lwork .GE. m*n + 3*m )
THEN
2078 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
2080 CALL cunmbr(
'P',
'R',
'C', m, n, m, a, lda,
2081 $ work( itaup ), work( ivt ), ldwkvt,
2082 $ work( nwork ), lwork-nwork+1, ierr )
2083 CALL clacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
2092 CALL cungbr(
'P', m, n, m, a, lda, work( itaup ),
2093 $ work( nwork ), lwork-nwork+1, ierr )
2103 DO 60 i = 1, n, chunk
2104 blk = min( n-i+1, chunk )
2105 CALL clarcm( m, blk, rwork( irvt ), m, a( 1, i ),
2106 $ lda, work( ivt ), ldwkvt,
2108 CALL clacpy(
'F', m, blk, work( ivt ), ldwkvt,
2112 ELSE IF( wntqs )
THEN
2124 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2125 $ m, rwork( irvt ), m, dum, idum,
2126 $ rwork( nrwork ), iwork, info )
2134 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2135 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2136 $ work( itauq ), u, ldu, work( nwork ),
2137 $ lwork-nwork+1, ierr )
2145 CALL claset(
'F', m, n, czero, czero, vt, ldvt )
2146 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
2147 CALL cunmbr(
'P',
'R',
'C', m, n, m, a, lda,
2148 $ work( itaup ), vt, ldvt, work( nwork ),
2149 $ lwork-nwork+1, ierr )
2163 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2164 $ m, rwork( irvt ), m, dum, idum,
2165 $ rwork( nrwork ), iwork, info )
2173 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2174 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2175 $ work( itauq ), u, ldu, work( nwork ),
2176 $ lwork-nwork+1, ierr )
2180 CALL claset(
'F', n, n, czero, cone, vt, ldvt )
2188 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
2189 CALL cunmbr(
'P',
'R',
'C', n, n, m, a, lda,
2190 $ work( itaup ), vt, ldvt, work( nwork ),
2191 $ lwork-nwork+1, ierr )
2200 IF( iscl.EQ.1 )
THEN
2201 IF( anrm.GT.bignum )
2202 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
2204 IF( info.NE.0 .AND. anrm.GT.bignum )
2205 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn-1, 1,
2206 $ rwork( ie ), minmn, ierr )
2207 IF( anrm.LT.smlnum )
2208 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
2210 IF( info.NE.0 .AND. anrm.LT.smlnum )
2211 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn-1, 1,
2212 $ rwork( ie ), minmn, ierr )
2217 work( 1 ) = sroundup_lwork( maxwrk )
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