219 SUBROUTINE cgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
220 $ WORK, LWORK, RWORK, IWORK, INFO )
229 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
233 REAL RWORK( * ), S( * )
234 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
242 parameter( czero = ( 0.0e+0, 0.0e+0 ),
243 $ cone = ( 1.0e+0, 0.0e+0 ) )
245 parameter( zero = 0.0e+0, one = 1.0e+0 )
248 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
249 INTEGER BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
250 $ iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
251 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
252 $ mnthr1, mnthr2, nrwork, nwork, wrkbl
253 INTEGER LWORK_CGEBRD_MN, LWORK_CGEBRD_MM,
254 $ lwork_cgebrd_nn, lwork_cgelqf_mn,
256 $ lwork_cungbr_p_mn, lwork_cungbr_p_nn,
257 $ lwork_cungbr_q_mn, lwork_cungbr_q_mm,
258 $ lwork_cunglq_mn, lwork_cunglq_nn,
259 $ lwork_cungqr_mm, lwork_cungqr_mn,
260 $ lwork_cunmbr_prc_mm, lwork_cunmbr_qln_mm,
261 $ lwork_cunmbr_prc_mn, lwork_cunmbr_qln_mn,
262 $ lwork_cunmbr_prc_nn, lwork_cunmbr_qln_nn
263 REAL ANRM, BIGNUM, EPS, SMLNUM
276 LOGICAL LSAME, SISNAN
277 REAL SLAMCH, CLANGE, SROUNDUP_LWORK
278 EXTERNAL lsame, slamch, clange, sisnan,
282 INTRINSIC int, max, min, sqrt
290 mnthr1 = int( minmn*17.0e0 / 9.0e0 )
291 mnthr2 = int( minmn*5.0e0 / 3.0e0 )
292 wntqa = lsame( jobz,
'A' )
293 wntqs = lsame( jobz,
'S' )
294 wntqas = wntqa .OR. wntqs
295 wntqo = lsame( jobz,
'O' )
296 wntqn = lsame( jobz,
'N' )
297 lquery = ( lwork.EQ.-1 )
301 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
303 ELSE IF( m.LT.0 )
THEN
305 ELSE IF( n.LT.0 )
THEN
307 ELSE IF( lda.LT.max( 1, m ) )
THEN
309 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
310 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
312 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
313 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
314 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
329 IF( m.GE.n .AND. minmn.GT.0 )
THEN
338 CALL cgebrd( m, n, cdum(1), m, dum(1), dum(1), cdum(1),
339 $ cdum(1), cdum(1), -1, ierr )
340 lwork_cgebrd_mn = int( cdum(1) )
342 CALL cgebrd( n, n, cdum(1), n, dum(1), dum(1), cdum(1),
343 $ cdum(1), cdum(1), -1, ierr )
344 lwork_cgebrd_nn = int( cdum(1) )
346 CALL cgeqrf( m, n, cdum(1), m, cdum(1), cdum(1), -1, ierr )
347 lwork_cgeqrf_mn = int( cdum(1) )
349 CALL cungbr(
'P', n, n, n, cdum(1), n, cdum(1), cdum(1),
351 lwork_cungbr_p_nn = int( cdum(1) )
353 CALL cungbr(
'Q', m, m, n, cdum(1), m, cdum(1), cdum(1),
355 lwork_cungbr_q_mm = int( cdum(1) )
357 CALL cungbr(
'Q', m, n, n, cdum(1), m, cdum(1), cdum(1),
359 lwork_cungbr_q_mn = int( cdum(1) )
361 CALL cungqr( m, m, n, cdum(1), m, cdum(1), cdum(1),
363 lwork_cungqr_mm = int( cdum(1) )
365 CALL cungqr( m, n, n, cdum(1), m, cdum(1), cdum(1),
367 lwork_cungqr_mn = int( cdum(1) )
369 CALL cunmbr(
'P',
'R',
'C', n, n, n, cdum(1), n, cdum(1),
370 $ cdum(1), n, cdum(1), -1, ierr )
371 lwork_cunmbr_prc_nn = int( cdum(1) )
373 CALL cunmbr(
'Q',
'L',
'N', m, m, n, cdum(1), m, cdum(1),
374 $ cdum(1), m, cdum(1), -1, ierr )
375 lwork_cunmbr_qln_mm = int( cdum(1) )
377 CALL cunmbr(
'Q',
'L',
'N', m, n, n, cdum(1), m, cdum(1),
378 $ cdum(1), m, cdum(1), -1, ierr )
379 lwork_cunmbr_qln_mn = int( cdum(1) )
381 CALL cunmbr(
'Q',
'L',
'N', n, n, n, cdum(1), n, cdum(1),
382 $ cdum(1), n, cdum(1), -1, ierr )
383 lwork_cunmbr_qln_nn = int( cdum(1) )
385 IF( m.GE.mnthr1 )
THEN
390 maxwrk = n + lwork_cgeqrf_mn
391 maxwrk = max( maxwrk, 2*n + lwork_cgebrd_nn )
393 ELSE IF( wntqo )
THEN
397 wrkbl = n + lwork_cgeqrf_mn
398 wrkbl = max( wrkbl, n + lwork_cungqr_mn )
399 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
400 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
401 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
402 maxwrk = m*n + n*n + wrkbl
404 ELSE IF( wntqs )
THEN
408 wrkbl = n + lwork_cgeqrf_mn
409 wrkbl = max( wrkbl, n + lwork_cungqr_mn )
410 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
411 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
412 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
415 ELSE IF( wntqa )
THEN
419 wrkbl = n + lwork_cgeqrf_mn
420 wrkbl = max( wrkbl, n + lwork_cungqr_mm )
421 wrkbl = max( wrkbl, 2*n + lwork_cgebrd_nn )
422 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_qln_nn )
423 wrkbl = max( wrkbl, 2*n + lwork_cunmbr_prc_nn )
425 minwrk = n*n + max( 3*n, n + m )
427 ELSE IF( m.GE.mnthr2 )
THEN
431 maxwrk = 2*n + lwork_cgebrd_mn
435 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
436 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mn )
437 maxwrk = maxwrk + m*n
438 minwrk = minwrk + n*n
439 ELSE IF( wntqs )
THEN
441 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
442 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mn )
443 ELSE IF( wntqa )
THEN
445 maxwrk = max( maxwrk, 2*n + lwork_cungbr_p_nn )
446 maxwrk = max( maxwrk, 2*n + lwork_cungbr_q_mm )
452 maxwrk = 2*n + lwork_cgebrd_mn
456 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
457 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mn )
458 maxwrk = maxwrk + m*n
459 minwrk = minwrk + n*n
460 ELSE IF( wntqs )
THEN
462 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mn )
463 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
464 ELSE IF( wntqa )
THEN
466 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_qln_mm )
467 maxwrk = max( maxwrk, 2*n + lwork_cunmbr_prc_nn )
470 ELSE IF( minmn.GT.0 )
THEN
479 CALL cgebrd( m, n, cdum(1), m, dum(1), dum(1), cdum(1),
480 $ cdum(1), cdum(1), -1, ierr )
481 lwork_cgebrd_mn = int( cdum(1) )
483 CALL cgebrd( m, m, cdum(1), m, dum(1), dum(1), cdum(1),
484 $ cdum(1), cdum(1), -1, ierr )
485 lwork_cgebrd_mm = int( cdum(1) )
487 CALL cgelqf( m, n, cdum(1), m, cdum(1), cdum(1), -1, ierr )
488 lwork_cgelqf_mn = int( cdum(1) )
490 CALL cungbr(
'P', m, n, m, cdum(1), m, cdum(1), cdum(1),
492 lwork_cungbr_p_mn = int( cdum(1) )
494 CALL cungbr(
'P', n, n, m, cdum(1), n, cdum(1), cdum(1),
496 lwork_cungbr_p_nn = int( cdum(1) )
498 CALL cungbr(
'Q', m, m, n, cdum(1), m, cdum(1), cdum(1),
500 lwork_cungbr_q_mm = int( cdum(1) )
502 CALL cunglq( m, n, m, cdum(1), m, cdum(1), cdum(1),
504 lwork_cunglq_mn = int( cdum(1) )
506 CALL cunglq( n, n, m, cdum(1), n, cdum(1), cdum(1),
508 lwork_cunglq_nn = int( cdum(1) )
510 CALL cunmbr(
'P',
'R',
'C', m, m, m, cdum(1), m, cdum(1),
511 $ cdum(1), m, cdum(1), -1, ierr )
512 lwork_cunmbr_prc_mm = int( cdum(1) )
514 CALL cunmbr(
'P',
'R',
'C', m, n, m, cdum(1), m, cdum(1),
515 $ cdum(1), m, cdum(1), -1, ierr )
516 lwork_cunmbr_prc_mn = int( cdum(1) )
518 CALL cunmbr(
'P',
'R',
'C', n, n, m, cdum(1), n, cdum(1),
519 $ cdum(1), n, cdum(1), -1, ierr )
520 lwork_cunmbr_prc_nn = int( cdum(1) )
522 CALL cunmbr(
'Q',
'L',
'N', m, m, m, cdum(1), m, cdum(1),
523 $ cdum(1), m, cdum(1), -1, ierr )
524 lwork_cunmbr_qln_mm = int( cdum(1) )
526 IF( n.GE.mnthr1 )
THEN
531 maxwrk = m + lwork_cgelqf_mn
532 maxwrk = max( maxwrk, 2*m + lwork_cgebrd_mm )
534 ELSE IF( wntqo )
THEN
538 wrkbl = m + lwork_cgelqf_mn
539 wrkbl = max( wrkbl, m + lwork_cunglq_mn )
540 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
541 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
542 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
543 maxwrk = m*n + m*m + wrkbl
545 ELSE IF( wntqs )
THEN
549 wrkbl = m + lwork_cgelqf_mn
550 wrkbl = max( wrkbl, m + lwork_cunglq_mn )
551 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
552 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
553 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
556 ELSE IF( wntqa )
THEN
560 wrkbl = m + lwork_cgelqf_mn
561 wrkbl = max( wrkbl, m + lwork_cunglq_nn )
562 wrkbl = max( wrkbl, 2*m + lwork_cgebrd_mm )
563 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_qln_mm )
564 wrkbl = max( wrkbl, 2*m + lwork_cunmbr_prc_mm )
566 minwrk = m*m + max( 3*m, m + n )
568 ELSE IF( n.GE.mnthr2 )
THEN
572 maxwrk = 2*m + lwork_cgebrd_mn
576 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
577 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_mn )
578 maxwrk = maxwrk + m*n
579 minwrk = minwrk + m*m
580 ELSE IF( wntqs )
THEN
582 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
583 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_mn )
584 ELSE IF( wntqa )
THEN
586 maxwrk = max( maxwrk, 2*m + lwork_cungbr_q_mm )
587 maxwrk = max( maxwrk, 2*m + lwork_cungbr_p_nn )
593 maxwrk = 2*m + lwork_cgebrd_mn
597 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
598 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_mn )
599 maxwrk = maxwrk + m*n
600 minwrk = minwrk + m*m
601 ELSE IF( wntqs )
THEN
603 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
604 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_mn )
605 ELSE IF( wntqa )
THEN
607 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_qln_mm )
608 maxwrk = max( maxwrk, 2*m + lwork_cunmbr_prc_nn )
612 maxwrk = max( maxwrk, minwrk )
615 work( 1 ) = sroundup_lwork( maxwrk )
616 IF( lwork.LT.minwrk .AND. .NOT. lquery )
THEN
622 CALL xerbla(
'CGESDD', -info )
624 ELSE IF( lquery )
THEN
630 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
637 smlnum = sqrt( slamch(
'S' ) ) / eps
638 bignum = one / smlnum
642 anrm = clange(
'M', m, n, a, lda, dum )
643 IF( sisnan( anrm ) )
THEN
648 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
650 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
651 ELSE IF( anrm.GT.bignum )
THEN
653 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
662 IF( m.GE.mnthr1 )
THEN
677 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
678 $ lwork-nwork+1, ierr )
682 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
694 CALL cgebrd( n, n, a, lda, s, rwork( ie ), work( itauq ),
695 $ work( itaup ), work( nwork ), lwork-nwork+1,
703 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum,1,dum,1,
704 $ dum, idum, rwork( nrwork ), iwork, info )
706 ELSE IF( wntqo )
THEN
718 IF( lwork .GE. m*n + n*n + 3*n )
THEN
724 ldwrkr = ( lwork - n*n - 3*n ) / n
734 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
735 $ lwork-nwork+1, ierr )
739 CALL clacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
740 CALL claset(
'L', n-1, n-1, czero, czero, work( ir+1 ),
748 CALL cungqr( m, n, n, a, lda, work( itau ),
749 $ work( nwork ), lwork-nwork+1, ierr )
760 CALL cgebrd( n, n, work( ir ), ldwrkr, s, rwork( ie ),
761 $ work( itauq ), work( itaup ), work( nwork ),
762 $ lwork-nwork+1, ierr )
773 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
774 $ n, rwork( irvt ), n, dum, idum,
775 $ rwork( nrwork ), iwork, info )
783 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
785 CALL cunmbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
786 $ work( itauq ), work( iu ), ldwrku,
787 $ work( nwork ), lwork-nwork+1, ierr )
795 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
796 CALL cunmbr(
'P',
'R',
'C', n, n, n, work( ir ), ldwrkr,
797 $ work( itaup ), vt, ldvt, work( nwork ),
798 $ lwork-nwork+1, ierr )
806 DO 10 i = 1, m, ldwrkr
807 chunk = min( m-i+1, ldwrkr )
808 CALL cgemm(
'N',
'N', chunk, n, n, cone, a( i, 1 ),
809 $ lda, work( iu ), ldwrku, czero,
810 $ work( ir ), ldwrkr )
811 CALL clacpy(
'F', chunk, n, work( ir ), ldwrkr,
815 ELSE IF( wntqs )
THEN
834 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
835 $ lwork-nwork+1, ierr )
839 CALL clacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
840 CALL claset(
'L', n-1, n-1, czero, czero, work( ir+1 ),
848 CALL cungqr( m, n, n, a, lda, work( itau ),
849 $ work( nwork ), lwork-nwork+1, ierr )
860 CALL cgebrd( n, n, work( ir ), ldwrkr, s, rwork( ie ),
861 $ work( itauq ), work( itaup ), work( nwork ),
862 $ lwork-nwork+1, ierr )
873 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
874 $ n, rwork( irvt ), n, dum, idum,
875 $ rwork( nrwork ), iwork, info )
883 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
884 CALL cunmbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
885 $ work( itauq ), u, ldu, work( nwork ),
886 $ lwork-nwork+1, ierr )
894 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
895 CALL cunmbr(
'P',
'R',
'C', n, n, n, work( ir ), ldwrkr,
896 $ work( itaup ), vt, ldvt, work( nwork ),
897 $ lwork-nwork+1, ierr )
904 CALL clacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
905 CALL cgemm(
'N',
'N', m, n, n, cone, a, lda, work( ir ),
906 $ ldwrkr, czero, u, ldu )
908 ELSE IF( wntqa )
THEN
927 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
928 $ lwork-nwork+1, ierr )
929 CALL clacpy(
'L', m, n, a, lda, u, ldu )
936 CALL cungqr( m, m, n, u, ldu, work( itau ),
937 $ work( nwork ), lwork-nwork+1, ierr )
941 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
953 CALL cgebrd( n, n, a, lda, s, rwork( ie ), work( itauq ),
954 $ work( itaup ), work( nwork ), lwork-nwork+1,
966 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
967 $ n, rwork( irvt ), n, dum, idum,
968 $ rwork( nrwork ), iwork, info )
976 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
978 CALL cunmbr(
'Q',
'L',
'N', n, n, n, a, lda,
979 $ work( itauq ), work( iu ), ldwrku,
980 $ work( nwork ), lwork-nwork+1, ierr )
988 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
989 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
990 $ work( itaup ), vt, ldvt, work( nwork ),
991 $ lwork-nwork+1, ierr )
998 CALL cgemm(
'N',
'N', m, n, n, cone, u, ldu, work( iu ),
999 $ ldwrku, czero, a, lda )
1003 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1007 ELSE IF( m.GE.mnthr2 )
THEN
1026 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1027 $ work( itaup ), work( nwork ), lwork-nwork+1,
1036 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum, 1,dum,1,
1037 $ dum, idum, rwork( nrwork ), iwork, info )
1038 ELSE IF( wntqo )
THEN
1050 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1051 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1052 $ work( nwork ), lwork-nwork+1, ierr )
1059 CALL cungbr(
'Q', m, n, n, a, lda, work( itauq ),
1060 $ work( nwork ), lwork-nwork+1, ierr )
1062 IF( lwork .GE. m*n + 3*n )
THEN
1071 ldwrku = ( lwork - 3*n ) / n
1073 nwork = iu + ldwrku*n
1081 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1082 $ n, rwork( irvt ), n, dum, idum,
1083 $ rwork( nrwork ), iwork, info )
1090 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt,
1091 $ work( iu ), ldwrku, rwork( nrwork ) )
1092 CALL clacpy(
'F', n, n, work( iu ), ldwrku, vt, ldvt )
1102 DO 20 i = 1, m, ldwrku
1103 chunk = min( m-i+1, ldwrku )
1104 CALL clacrm( chunk, n, a( i, 1 ), lda, rwork( iru ),
1105 $ n, work( iu ), ldwrku, rwork( nrwork ) )
1106 CALL clacpy(
'F', chunk, n, work( iu ), ldwrku,
1110 ELSE IF( wntqs )
THEN
1118 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1119 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1120 $ work( nwork ), lwork-nwork+1, ierr )
1127 CALL clacpy(
'L', m, n, a, lda, u, ldu )
1128 CALL cungbr(
'Q', m, n, n, u, ldu, work( itauq ),
1129 $ work( nwork ), lwork-nwork+1, ierr )
1140 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1141 $ n, rwork( irvt ), n, dum, idum,
1142 $ rwork( nrwork ), iwork, info )
1149 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt, a, lda,
1151 CALL clacpy(
'F', n, n, a, lda, vt, ldvt )
1159 CALL clacrm( m, n, u, ldu, rwork( iru ), n, a, lda,
1161 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1170 CALL clacpy(
'U', n, n, a, lda, vt, ldvt )
1171 CALL cungbr(
'P', n, n, n, vt, ldvt, work( itaup ),
1172 $ work( nwork ), lwork-nwork+1, ierr )
1179 CALL clacpy(
'L', m, n, a, lda, u, ldu )
1180 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1181 $ work( nwork ), lwork-nwork+1, ierr )
1192 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1193 $ n, rwork( irvt ), n, dum, idum,
1194 $ rwork( nrwork ), iwork, info )
1201 CALL clarcm( n, n, rwork( irvt ), n, vt, ldvt, a, lda,
1203 CALL clacpy(
'F', n, n, a, lda, vt, ldvt )
1211 CALL clacrm( m, n, u, ldu, rwork( iru ), n, a, lda,
1213 CALL clacpy(
'F', m, n, a, lda, u, ldu )
1235 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1236 $ work( itaup ), work( nwork ), lwork-nwork+1,
1245 CALL sbdsdc(
'U',
'N', n, s, rwork( ie ), dum,1,dum,1,
1246 $ dum, idum, rwork( nrwork ), iwork, info )
1247 ELSE IF( wntqo )
THEN
1252 IF( lwork .GE. m*n + 3*n )
THEN
1261 ldwrku = ( lwork - 3*n ) / n
1263 nwork = iu + ldwrku*n
1272 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1273 $ n, rwork( irvt ), n, dum, idum,
1274 $ rwork( nrwork ), iwork, info )
1282 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1283 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1284 $ work( itaup ), vt, ldvt, work( nwork ),
1285 $ lwork-nwork+1, ierr )
1287 IF( lwork .GE. m*n + 3*n )
THEN
1297 CALL claset(
'F', m, n, czero, czero, work( iu ),
1299 CALL clacp2(
'F', n, n, rwork( iru ), n, work( iu ),
1301 CALL cunmbr(
'Q',
'L',
'N', m, n, n, a, lda,
1302 $ work( itauq ), work( iu ), ldwrku,
1303 $ work( nwork ), lwork-nwork+1, ierr )
1304 CALL clacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
1313 CALL cungbr(
'Q', m, n, n, a, lda, work( itauq ),
1314 $ work( nwork ), lwork-nwork+1, ierr )
1324 DO 30 i = 1, m, ldwrku
1325 chunk = min( m-i+1, ldwrku )
1326 CALL clacrm( chunk, n, a( i, 1 ), lda,
1327 $ rwork( iru ), n, work( iu ), ldwrku,
1329 CALL clacpy(
'F', chunk, n, work( iu ), ldwrku,
1334 ELSE IF( wntqs )
THEN
1346 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1347 $ n, rwork( irvt ), n, dum, idum,
1348 $ rwork( nrwork ), iwork, info )
1356 CALL claset(
'F', m, n, czero, czero, u, ldu )
1357 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
1358 CALL cunmbr(
'Q',
'L',
'N', m, n, n, a, lda,
1359 $ work( itauq ), u, ldu, work( nwork ),
1360 $ lwork-nwork+1, ierr )
1368 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1369 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1370 $ work( itaup ), vt, ldvt, work( nwork ),
1371 $ lwork-nwork+1, ierr )
1384 CALL sbdsdc(
'U',
'I', n, s, rwork( ie ), rwork( iru ),
1385 $ n, rwork( irvt ), n, dum, idum,
1386 $ rwork( nrwork ), iwork, info )
1390 CALL claset(
'F', m, m, czero, czero, u, ldu )
1392 CALL claset(
'F', m-n, m-n, czero, cone,
1393 $ u( n+1, n+1 ), ldu )
1402 CALL clacp2(
'F', n, n, rwork( iru ), n, u, ldu )
1403 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
1404 $ work( itauq ), u, ldu, work( nwork ),
1405 $ lwork-nwork+1, ierr )
1413 CALL clacp2(
'F', n, n, rwork( irvt ), n, vt, ldvt )
1414 CALL cunmbr(
'P',
'R',
'C', n, n, n, a, lda,
1415 $ work( itaup ), vt, ldvt, work( nwork ),
1416 $ lwork-nwork+1, ierr )
1427 IF( n.GE.mnthr1 )
THEN
1442 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1443 $ lwork-nwork+1, ierr )
1447 CALL claset(
'U', m-1, m-1, czero, czero, a( 1, 2 ),
1459 CALL cgebrd( m, m, a, lda, s, rwork( ie ), work( itauq ),
1460 $ work( itaup ), work( nwork ), lwork-nwork+1,
1468 CALL sbdsdc(
'U',
'N', m, s, rwork( ie ), dum,1,dum,1,
1469 $ dum, idum, rwork( nrwork ), iwork, info )
1471 ELSE IF( wntqo )
THEN
1483 IF( lwork .GE. m*n + m*m + 3*m )
THEN
1494 chunk = ( lwork - m*m - 3*m ) / m
1496 itau = il + ldwrkl*chunk
1504 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1505 $ lwork-nwork+1, ierr )
1509 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1510 CALL claset(
'U', m-1, m-1, czero, czero,
1511 $ work( il+ldwrkl ), ldwrkl )
1518 CALL cunglq( m, n, m, a, lda, work( itau ),
1519 $ work( nwork ), lwork-nwork+1, ierr )
1530 CALL cgebrd( m, m, work( il ), ldwrkl, s, rwork( ie ),
1531 $ work( itauq ), work( itaup ), work( nwork ),
1532 $ lwork-nwork+1, ierr )
1543 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1544 $ m, rwork( irvt ), m, dum, idum,
1545 $ rwork( nrwork ), iwork, info )
1553 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1554 CALL cunmbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1555 $ work( itauq ), u, ldu, work( nwork ),
1556 $ lwork-nwork+1, ierr )
1564 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
1566 CALL cunmbr(
'P',
'R',
'C', m, m, m, work( il ), ldwrkl,
1567 $ work( itaup ), work( ivt ), ldwkvt,
1568 $ work( nwork ), lwork-nwork+1, ierr )
1576 DO 40 i = 1, n, chunk
1577 blk = min( n-i+1, chunk )
1578 CALL cgemm(
'N',
'N', m, blk, m, cone, work( ivt ), m,
1579 $ a( 1, i ), lda, czero, work( il ),
1581 CALL clacpy(
'F', m, blk, work( il ), ldwrkl,
1585 ELSE IF( wntqs )
THEN
1596 itau = il + ldwrkl*m
1604 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1605 $ lwork-nwork+1, ierr )
1609 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1610 CALL claset(
'U', m-1, m-1, czero, czero,
1611 $ work( il+ldwrkl ), ldwrkl )
1618 CALL cunglq( m, n, m, a, lda, work( itau ),
1619 $ work( nwork ), lwork-nwork+1, ierr )
1630 CALL cgebrd( m, m, work( il ), ldwrkl, s, rwork( ie ),
1631 $ work( itauq ), work( itaup ), work( nwork ),
1632 $ lwork-nwork+1, ierr )
1643 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1644 $ m, rwork( irvt ), m, dum, idum,
1645 $ rwork( nrwork ), iwork, info )
1653 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1654 CALL cunmbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1655 $ work( itauq ), u, ldu, work( nwork ),
1656 $ lwork-nwork+1, ierr )
1664 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
1665 CALL cunmbr(
'P',
'R',
'C', m, m, m, work( il ), ldwrkl,
1666 $ work( itaup ), vt, ldvt, work( nwork ),
1667 $ lwork-nwork+1, ierr )
1674 CALL clacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1675 CALL cgemm(
'N',
'N', m, n, m, cone, work( il ), ldwrkl,
1676 $ a, lda, czero, vt, ldvt )
1678 ELSE IF( wntqa )
THEN
1689 itau = ivt + ldwkvt*m
1697 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
1698 $ lwork-nwork+1, ierr )
1699 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1706 CALL cunglq( n, n, m, vt, ldvt, work( itau ),
1707 $ work( nwork ), lwork-nwork+1, ierr )
1711 CALL claset(
'U', m-1, m-1, czero, czero, a( 1, 2 ),
1723 CALL cgebrd( m, m, a, lda, s, rwork( ie ), work( itauq ),
1724 $ work( itaup ), work( nwork ), lwork-nwork+1,
1736 CALL sbdsdc(
'U',
'I', m, s, rwork( ie ), rwork( iru ),
1737 $ m, rwork( irvt ), m, dum, idum,
1738 $ rwork( nrwork ), iwork, info )
1746 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
1747 CALL cunmbr(
'Q',
'L',
'N', m, m, m, a, lda,
1748 $ work( itauq ), u, ldu, work( nwork ),
1749 $ lwork-nwork+1, ierr )
1757 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
1759 CALL cunmbr(
'P',
'R',
'C', m, m, m, a, lda,
1760 $ work( itaup ), work( ivt ), ldwkvt,
1761 $ work( nwork ), lwork-nwork+1, ierr )
1768 CALL cgemm(
'N',
'N', m, n, m, cone, work( ivt ), ldwkvt,
1769 $ vt, ldvt, czero, a, lda )
1773 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1777 ELSE IF( n.GE.mnthr2 )
THEN
1796 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
1797 $ work( itaup ), work( nwork ), lwork-nwork+1,
1807 CALL sbdsdc(
'L',
'N', m, s, rwork( ie ), dum,1,dum,1,
1808 $ dum, idum, rwork( nrwork ), iwork, info )
1809 ELSE IF( wntqo )
THEN
1821 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1822 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1823 $ work( nwork ), lwork-nwork+1, ierr )
1830 CALL cungbr(
'P', m, n, m, a, lda, work( itaup ),
1831 $ work( nwork ), lwork-nwork+1, ierr )
1834 IF( lwork .GE. m*n + 3*m )
THEN
1838 nwork = ivt + ldwkvt*n
1844 chunk = ( lwork - 3*m ) / m
1845 nwork = ivt + ldwkvt*chunk
1854 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1855 $ m, rwork( irvt ), m, dum, idum,
1856 $ rwork( nrwork ), iwork, info )
1863 CALL clacrm( m, m, u, ldu, rwork( iru ), m, work( ivt ),
1864 $ ldwkvt, rwork( nrwork ) )
1865 CALL clacpy(
'F', m, m, work( ivt ), ldwkvt, u, ldu )
1875 DO 50 i = 1, n, chunk
1876 blk = min( n-i+1, chunk )
1877 CALL clarcm( m, blk, rwork( irvt ), m, a( 1, i ), lda,
1878 $ work( ivt ), ldwkvt, rwork( nrwork ) )
1879 CALL clacpy(
'F', m, blk, work( ivt ), ldwkvt,
1882 ELSE IF( wntqs )
THEN
1890 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1891 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1892 $ work( nwork ), lwork-nwork+1, ierr )
1899 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1900 CALL cungbr(
'P', m, n, m, vt, ldvt, work( itaup ),
1901 $ work( nwork ), lwork-nwork+1, ierr )
1912 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1913 $ m, rwork( irvt ), m, dum, idum,
1914 $ rwork( nrwork ), iwork, info )
1921 CALL clacrm( m, m, u, ldu, rwork( iru ), m, a, lda,
1923 CALL clacpy(
'F', m, m, a, lda, u, ldu )
1931 CALL clarcm( m, n, rwork( irvt ), m, vt, ldvt, a, lda,
1933 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
1942 CALL clacpy(
'L', m, m, a, lda, u, ldu )
1943 CALL cungbr(
'Q', m, m, n, u, ldu, work( itauq ),
1944 $ work( nwork ), lwork-nwork+1, ierr )
1951 CALL clacpy(
'U', m, n, a, lda, vt, ldvt )
1952 CALL cungbr(
'P', n, n, m, vt, ldvt, work( itaup ),
1953 $ work( nwork ), lwork-nwork+1, ierr )
1964 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
1965 $ m, rwork( irvt ), m, dum, idum,
1966 $ rwork( nrwork ), iwork, info )
1973 CALL clacrm( m, m, u, ldu, rwork( iru ), m, a, lda,
1975 CALL clacpy(
'F', m, m, a, lda, u, ldu )
1983 CALL clarcm( m, n, rwork( irvt ), m, vt, ldvt, a, lda,
1985 CALL clacpy(
'F', m, n, a, lda, vt, ldvt )
2007 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
2008 $ work( itaup ), work( nwork ), lwork-nwork+1,
2017 CALL sbdsdc(
'L',
'N', m, s, rwork( ie ), dum,1,dum,1,
2018 $ dum, idum, rwork( nrwork ), iwork, info )
2019 ELSE IF( wntqo )
THEN
2023 IF( lwork .GE. m*n + 3*m )
THEN
2027 CALL claset(
'F', m, n, czero, czero, work( ivt ),
2029 nwork = ivt + ldwkvt*n
2034 chunk = ( lwork - 3*m ) / m
2035 nwork = ivt + ldwkvt*chunk
2047 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2048 $ m, rwork( irvt ), m, dum, idum,
2049 $ rwork( nrwork ), iwork, info )
2057 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2058 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2059 $ work( itauq ), u, ldu, work( nwork ),
2060 $ lwork-nwork+1, ierr )
2062 IF( lwork .GE. m*n + 3*m )
THEN
2072 CALL clacp2(
'F', m, m, rwork( irvt ), m, work( ivt ),
2074 CALL cunmbr(
'P',
'R',
'C', m, n, m, a, lda,
2075 $ work( itaup ), work( ivt ), ldwkvt,
2076 $ work( nwork ), lwork-nwork+1, ierr )
2077 CALL clacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
2086 CALL cungbr(
'P', m, n, m, a, lda, work( itaup ),
2087 $ work( nwork ), lwork-nwork+1, ierr )
2097 DO 60 i = 1, n, chunk
2098 blk = min( n-i+1, chunk )
2099 CALL clarcm( m, blk, rwork( irvt ), m, a( 1, i ),
2100 $ lda, work( ivt ), ldwkvt,
2102 CALL clacpy(
'F', m, blk, work( ivt ), ldwkvt,
2106 ELSE IF( wntqs )
THEN
2118 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2119 $ m, rwork( irvt ), m, dum, idum,
2120 $ rwork( nrwork ), iwork, info )
2128 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2129 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2130 $ work( itauq ), u, ldu, work( nwork ),
2131 $ lwork-nwork+1, ierr )
2139 CALL claset(
'F', m, n, czero, czero, vt, ldvt )
2140 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
2141 CALL cunmbr(
'P',
'R',
'C', m, n, m, a, lda,
2142 $ work( itaup ), vt, ldvt, work( nwork ),
2143 $ lwork-nwork+1, ierr )
2157 CALL sbdsdc(
'L',
'I', m, s, rwork( ie ), rwork( iru ),
2158 $ m, rwork( irvt ), m, dum, idum,
2159 $ rwork( nrwork ), iwork, info )
2167 CALL clacp2(
'F', m, m, rwork( iru ), m, u, ldu )
2168 CALL cunmbr(
'Q',
'L',
'N', m, m, n, a, lda,
2169 $ work( itauq ), u, ldu, work( nwork ),
2170 $ lwork-nwork+1, ierr )
2174 CALL claset(
'F', n, n, czero, cone, vt, ldvt )
2182 CALL clacp2(
'F', m, m, rwork( irvt ), m, vt, ldvt )
2183 CALL cunmbr(
'P',
'R',
'C', n, n, m, a, lda,
2184 $ work( itaup ), vt, ldvt, work( nwork ),
2185 $ lwork-nwork+1, ierr )
2194 IF( iscl.EQ.1 )
THEN
2195 IF( anrm.GT.bignum )
2196 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
2198 IF( info.NE.0 .AND. anrm.GT.bignum )
2199 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn-1, 1,
2200 $ rwork( ie ), minmn, ierr )
2201 IF( anrm.LT.smlnum )
2202 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
2204 IF( info.NE.0 .AND. anrm.LT.smlnum )
2205 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn-1, 1,
2206 $ rwork( ie ), minmn, ierr )
2211 work( 1 ) = sroundup_lwork( maxwrk )
subroutine xerbla(srname, info)
subroutine sbdsdc(uplo, compq, n, d, e, u, ldu, vt, ldvt, q, iq, work, iwork, info)
SBDSDC
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 cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
subroutine cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
subroutine cgesdd(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, iwork, info)
CGESDD
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 clacrm(m, n, a, lda, b, ldb, c, ldc, rwork)
CLACRM multiplies a complex matrix by a square real matrix.
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 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 cungbr(vect, m, n, k, a, lda, tau, work, lwork, info)
CUNGBR
subroutine cunglq(m, n, k, a, lda, tau, work, lwork, info)
CUNGLQ
subroutine cungqr(m, n, k, a, lda, tau, work, lwork, info)
CUNGQR
subroutine cunmbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMBR