211 SUBROUTINE dgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
212 $ WORK, LWORK, IWORK, INFO )
221 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
225 DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),
226 $ vt( ldvt, * ), work( * )
232 DOUBLE PRECISION ZERO, ONE
233 parameter( zero = 0.0d0, one = 1.0d0 )
236 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
237 INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
238 $ ir, iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
239 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
240 $ mnthr, nwork, wrkbl
241 INTEGER LWORK_DGEBRD_MN, LWORK_DGEBRD_MM,
242 $ lwork_dgebrd_nn, lwork_dgelqf_mn,
244 $ lwork_dorgbr_p_mm, lwork_dorgbr_q_nn,
245 $ lwork_dorglq_mn, lwork_dorglq_nn,
246 $ lwork_dorgqr_mm, lwork_dorgqr_mn,
247 $ lwork_dormbr_prt_mm, lwork_dormbr_qln_mm,
248 $ lwork_dormbr_prt_mn, lwork_dormbr_qln_mn,
249 $ lwork_dormbr_prt_nn, lwork_dormbr_qln_nn
250 DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
254 DOUBLE PRECISION DUM( 1 )
262 LOGICAL LSAME, DISNAN
263 DOUBLE PRECISION DLAMCH, DLANGE, DROUNDUP_LWORK
264 EXTERNAL dlamch, dlange, lsame, disnan,
268 INTRINSIC int, max, min, sqrt
276 wntqa = lsame( jobz,
'A' )
277 wntqs = lsame( jobz,
'S' )
278 wntqas = wntqa .OR. wntqs
279 wntqo = lsame( jobz,
'O' )
280 wntqn = lsame( jobz,
'N' )
281 lquery = ( lwork.EQ.-1 )
283 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
285 ELSE IF( m.LT.0 )
THEN
287 ELSE IF( n.LT.0 )
THEN
289 ELSE IF( lda.LT.max( 1, m ) )
THEN
291 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
292 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
294 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
295 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
296 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
311 mnthr = int( minmn*11.0d0 / 6.0d0 )
312 IF( m.GE.n .AND. minmn.GT.0 )
THEN
325 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
326 $ dum(1), dum(1), -1, ierr )
327 lwork_dgebrd_mn = int( dum(1) )
329 CALL dgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
330 $ dum(1), dum(1), -1, ierr )
331 lwork_dgebrd_nn = int( dum(1) )
333 CALL dgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
334 lwork_dgeqrf_mn = int( dum(1) )
336 CALL dorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
338 lwork_dorgbr_q_nn = int( dum(1) )
340 CALL dorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
341 lwork_dorgqr_mm = int( dum(1) )
343 CALL dorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
344 lwork_dorgqr_mn = int( dum(1) )
346 CALL dormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
347 $ dum(1), dum(1), n, dum(1), -1, ierr )
348 lwork_dormbr_prt_nn = int( dum(1) )
350 CALL dormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
351 $ dum(1), dum(1), n, dum(1), -1, ierr )
352 lwork_dormbr_qln_nn = int( dum(1) )
354 CALL dormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
355 $ dum(1), dum(1), m, dum(1), -1, ierr )
356 lwork_dormbr_qln_mn = int( dum(1) )
358 CALL dormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
359 $ dum(1), dum(1), m, dum(1), -1, ierr )
360 lwork_dormbr_qln_mm = int( dum(1) )
362 IF( m.GE.mnthr )
THEN
367 wrkbl = n + lwork_dgeqrf_mn
368 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
369 maxwrk = max( wrkbl, bdspac + n )
371 ELSE IF( wntqo )
THEN
375 wrkbl = n + lwork_dgeqrf_mn
376 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
377 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
378 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
379 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
380 wrkbl = max( wrkbl, 3*n + bdspac )
381 maxwrk = wrkbl + 2*n*n
382 minwrk = bdspac + 2*n*n + 3*n
383 ELSE IF( wntqs )
THEN
387 wrkbl = n + lwork_dgeqrf_mn
388 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
389 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
390 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
391 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
392 wrkbl = max( wrkbl, 3*n + bdspac )
394 minwrk = bdspac + n*n + 3*n
395 ELSE IF( wntqa )
THEN
399 wrkbl = n + lwork_dgeqrf_mn
400 wrkbl = max( wrkbl, n + lwork_dorgqr_mm )
401 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
402 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
403 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
404 wrkbl = max( wrkbl, 3*n + bdspac )
406 minwrk = n*n + max( 3*n + bdspac, n + m )
412 wrkbl = 3*n + lwork_dgebrd_mn
415 maxwrk = max( wrkbl, 3*n + bdspac )
416 minwrk = 3*n + max( m, bdspac )
417 ELSE IF( wntqo )
THEN
419 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
420 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
421 wrkbl = max( wrkbl, 3*n + bdspac )
423 minwrk = 3*n + max( m, n*n + bdspac )
424 ELSE IF( wntqs )
THEN
426 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
427 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
428 maxwrk = max( wrkbl, 3*n + bdspac )
429 minwrk = 3*n + max( m, bdspac )
430 ELSE IF( wntqa )
THEN
432 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mm )
433 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
434 maxwrk = max( wrkbl, 3*n + bdspac )
435 minwrk = 3*n + max( m, bdspac )
438 ELSE IF( minmn.GT.0 )
THEN
451 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
452 $ dum(1), dum(1), -1, ierr )
453 lwork_dgebrd_mn = int( dum(1) )
455 CALL dgebrd( m, m, a, m, s, dum(1), dum(1),
456 $ dum(1), dum(1), -1, ierr )
457 lwork_dgebrd_mm = int( dum(1) )
459 CALL dgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
460 lwork_dgelqf_mn = int( dum(1) )
462 CALL dorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
463 lwork_dorglq_nn = int( dum(1) )
465 CALL dorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
466 lwork_dorglq_mn = int( dum(1) )
468 CALL dorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
469 lwork_dorgbr_p_mm = int( dum(1) )
471 CALL dormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
472 $ dum(1), dum(1), m, dum(1), -1, ierr )
473 lwork_dormbr_prt_mm = int( dum(1) )
475 CALL dormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
476 $ dum(1), dum(1), m, dum(1), -1, ierr )
477 lwork_dormbr_prt_mn = int( dum(1) )
479 CALL dormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
480 $ dum(1), dum(1), n, dum(1), -1, ierr )
481 lwork_dormbr_prt_nn = int( dum(1) )
483 CALL dormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
484 $ dum(1), dum(1), m, dum(1), -1, ierr )
485 lwork_dormbr_qln_mm = int( dum(1) )
487 IF( n.GE.mnthr )
THEN
492 wrkbl = m + lwork_dgelqf_mn
493 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
494 maxwrk = max( wrkbl, bdspac + m )
496 ELSE IF( wntqo )
THEN
500 wrkbl = m + lwork_dgelqf_mn
501 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
502 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
503 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
504 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
505 wrkbl = max( wrkbl, 3*m + bdspac )
506 maxwrk = wrkbl + 2*m*m
507 minwrk = bdspac + 2*m*m + 3*m
508 ELSE IF( wntqs )
THEN
512 wrkbl = m + lwork_dgelqf_mn
513 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
514 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
515 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
516 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
517 wrkbl = max( wrkbl, 3*m + bdspac )
519 minwrk = bdspac + m*m + 3*m
520 ELSE IF( wntqa )
THEN
524 wrkbl = m + lwork_dgelqf_mn
525 wrkbl = max( wrkbl, m + lwork_dorglq_nn )
526 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
527 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
528 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
529 wrkbl = max( wrkbl, 3*m + bdspac )
531 minwrk = m*m + max( 3*m + bdspac, m + n )
537 wrkbl = 3*m + lwork_dgebrd_mn
540 maxwrk = max( wrkbl, 3*m + bdspac )
541 minwrk = 3*m + max( n, bdspac )
542 ELSE IF( wntqo )
THEN
544 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
545 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
546 wrkbl = max( wrkbl, 3*m + bdspac )
548 minwrk = 3*m + max( n, m*m + bdspac )
549 ELSE IF( wntqs )
THEN
551 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
552 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
553 maxwrk = max( wrkbl, 3*m + bdspac )
554 minwrk = 3*m + max( n, bdspac )
555 ELSE IF( wntqa )
THEN
557 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
558 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_nn )
559 maxwrk = max( wrkbl, 3*m + bdspac )
560 minwrk = 3*m + max( n, bdspac )
565 maxwrk = max( maxwrk, minwrk )
566 work( 1 ) = droundup_lwork( maxwrk )
568 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
574 CALL xerbla(
'DGESDD', -info )
576 ELSE IF( lquery )
THEN
582 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
589 smlnum = sqrt( dlamch(
'S' ) ) / eps
590 bignum = one / smlnum
594 anrm = dlange(
'M', m, n, a, lda, dum )
595 IF( disnan( anrm ) )
THEN
600 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
602 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
603 ELSE IF( anrm.GT.bignum )
THEN
605 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
614 IF( m.GE.mnthr )
THEN
628 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
629 $ lwork - nwork + 1, ierr )
633 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
643 CALL dgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
644 $ work( itaup ), work( nwork ), lwork-nwork+1,
651 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
652 $ dum, idum, work( nwork ), iwork, info )
654 ELSE IF( wntqo )
THEN
664 IF( lwork .GE. lda*n + n*n + 3*n + bdspac )
THEN
667 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
676 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
677 $ lwork - nwork + 1, ierr )
681 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
682 CALL dlaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
689 CALL dorgqr( m, n, n, a, lda, work( itau ),
690 $ work( nwork ), lwork - nwork + 1, ierr )
700 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
701 $ work( itauq ), work( itaup ), work( nwork ),
702 $ lwork - nwork + 1, ierr )
714 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
715 $ vt, ldvt, dum, idum, work( nwork ), iwork,
723 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
724 $ work( itauq ), work( iu ), n, work( nwork ),
725 $ lwork - nwork + 1, ierr )
726 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
727 $ work( itaup ), vt, ldvt, work( nwork ),
728 $ lwork - nwork + 1, ierr )
735 DO 10 i = 1, m, ldwrkr
736 chunk = min( m - i + 1, ldwrkr )
737 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
738 $ lda, work( iu ), n, zero, work( ir ),
740 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
744 ELSE IF( wntqs )
THEN
762 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
763 $ lwork - nwork + 1, ierr )
767 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
768 CALL dlaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
775 CALL dorgqr( m, n, n, a, lda, work( itau ),
776 $ work( nwork ), lwork - nwork + 1, ierr )
786 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
787 $ work( itauq ), work( itaup ), work( nwork ),
788 $ lwork - nwork + 1, ierr )
795 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
796 $ ldvt, dum, idum, work( nwork ), iwork,
804 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
805 $ work( itauq ), u, ldu, work( nwork ),
806 $ lwork - nwork + 1, ierr )
808 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
809 $ work( itaup ), vt, ldvt, work( nwork ),
810 $ lwork - nwork + 1, ierr )
816 CALL dlacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
817 CALL dgemm(
'N',
'N', m, n, n, one, a, lda, work( ir ),
818 $ ldwrkr, zero, u, ldu )
820 ELSE IF( wntqa )
THEN
838 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
839 $ lwork - nwork + 1, ierr )
840 CALL dlacpy(
'L', m, n, a, lda, u, ldu )
845 CALL dorgqr( m, m, n, u, ldu, work( itau ),
846 $ work( nwork ), lwork - nwork + 1, ierr )
850 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
860 CALL dgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
861 $ work( itaup ), work( nwork ), lwork-nwork+1,
869 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
870 $ vt, ldvt, dum, idum, work( nwork ), iwork,
878 CALL dormbr(
'Q',
'L',
'N', n, n, n, a, lda,
879 $ work( itauq ), work( iu ), ldwrku,
880 $ work( nwork ), lwork - nwork + 1, ierr )
881 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
882 $ work( itaup ), vt, ldvt, work( nwork ),
883 $ lwork - nwork + 1, ierr )
889 CALL dgemm(
'N',
'N', m, n, n, one, u, ldu, work( iu ),
890 $ ldwrku, zero, a, lda )
894 CALL dlacpy(
'F', m, n, a, lda, u, ldu )
914 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
915 $ work( itaup ), work( nwork ), lwork-nwork+1,
923 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
924 $ dum, idum, work( nwork ), iwork, info )
925 ELSE IF( wntqo )
THEN
928 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
933 nwork = iu + ldwrku*n
934 CALL dlaset(
'F', m, n, zero, zero, work( iu ),
943 nwork = iu + ldwrku*n
948 ldwrkr = ( lwork - n*n - 3*n ) / n
950 nwork = iu + ldwrku*n
957 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
958 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
965 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
966 $ work( itaup ), vt, ldvt, work( nwork ),
967 $ lwork - nwork + 1, ierr )
969 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
976 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
977 $ work( itauq ), work( iu ), ldwrku,
978 $ work( nwork ), lwork - nwork + 1, ierr )
982 CALL dlacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
990 CALL dorgbr(
'Q', m, n, n, a, lda, work( itauq ),
991 $ work( nwork ), lwork - nwork + 1, ierr )
999 DO 20 i = 1, m, ldwrkr
1000 chunk = min( m - i + 1, ldwrkr )
1001 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
1002 $ lda, work( iu ), ldwrku, zero,
1003 $ work( ir ), ldwrkr )
1004 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
1009 ELSE IF( wntqs )
THEN
1017 CALL dlaset(
'F', m, n, zero, zero, u, ldu )
1018 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1019 $ ldvt, dum, idum, work( nwork ), iwork,
1027 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1028 $ work( itauq ), u, ldu, work( nwork ),
1029 $ lwork - nwork + 1, ierr )
1030 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
1031 $ work( itaup ), vt, ldvt, work( nwork ),
1032 $ lwork - nwork + 1, ierr )
1033 ELSE IF( wntqa )
THEN
1041 CALL dlaset(
'F', m, m, zero, zero, u, ldu )
1042 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1043 $ ldvt, dum, idum, work( nwork ), iwork,
1049 CALL dlaset(
'F', m - n, m - n, zero, one, u(n+1,n+1),
1058 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1059 $ work( itauq ), u, ldu, work( nwork ),
1060 $ lwork - nwork + 1, ierr )
1061 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1062 $ work( itaup ), vt, ldvt, work( nwork ),
1063 $ lwork - nwork + 1, ierr )
1074 IF( n.GE.mnthr )
THEN
1088 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1089 $ lwork - nwork + 1, ierr )
1093 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1103 CALL dgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1104 $ work( itaup ), work( nwork ), lwork-nwork+1,
1111 CALL dbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum, 1,
1112 $ dum, idum, work( nwork ), iwork, info )
1114 ELSE IF( wntqo )
THEN
1126 IF( lwork .GE. m*n + m*m + 3*m + bdspac )
THEN
1131 chunk = ( lwork - m*m ) / m
1133 itau = il + ldwrkl*m
1140 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1141 $ lwork - nwork + 1, ierr )
1145 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1146 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1147 $ work( il + ldwrkl ), ldwrkl )
1153 CALL dorglq( m, n, m, a, lda, work( itau ),
1154 $ work( nwork ), lwork - nwork + 1, ierr )
1164 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1165 $ work( itauq ), work( itaup ), work( nwork ),
1166 $ lwork - nwork + 1, ierr )
1173 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1174 $ work( ivt ), m, dum, idum, work( nwork ),
1182 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1183 $ work( itauq ), u, ldu, work( nwork ),
1184 $ lwork - nwork + 1, ierr )
1185 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1186 $ work( itaup ), work( ivt ), m,
1187 $ work( nwork ), lwork - nwork + 1, ierr )
1195 DO 30 i = 1, n, chunk
1196 blk = min( n - i + 1, chunk )
1197 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ), m,
1198 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1199 CALL dlacpy(
'F', m, blk, work( il ), ldwrkl,
1203 ELSE IF( wntqs )
THEN
1214 itau = il + ldwrkl*m
1221 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1222 $ lwork - nwork + 1, ierr )
1226 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1227 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1228 $ work( il + ldwrkl ), ldwrkl )
1234 CALL dorglq( m, n, m, a, lda, work( itau ),
1235 $ work( nwork ), lwork - nwork + 1, ierr )
1245 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1246 $ work( itauq ), work( itaup ), work( nwork ),
1247 $ lwork - nwork + 1, ierr )
1254 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1255 $ ldvt, dum, idum, work( nwork ), iwork,
1263 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1264 $ work( itauq ), u, ldu, work( nwork ),
1265 $ lwork - nwork + 1, ierr )
1266 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1267 $ work( itaup ), vt, ldvt, work( nwork ),
1268 $ lwork - nwork + 1, ierr )
1274 CALL dlacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1275 CALL dgemm(
'N',
'N', m, n, m, one, work( il ), ldwrkl,
1276 $ a, lda, zero, vt, ldvt )
1278 ELSE IF( wntqa )
THEN
1289 itau = ivt + ldwkvt*m
1296 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1297 $ lwork - nwork + 1, ierr )
1298 CALL dlacpy(
'U', m, n, a, lda, vt, ldvt )
1304 CALL dorglq( n, n, m, vt, ldvt, work( itau ),
1305 $ work( nwork ), lwork - nwork + 1, ierr )
1309 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1319 CALL dgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1320 $ work( itaup ), work( nwork ), lwork-nwork+1,
1328 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1329 $ work( ivt ), ldwkvt, dum, idum,
1330 $ work( nwork ), iwork, info )
1337 CALL dormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1338 $ work( itauq ), u, ldu, work( nwork ),
1339 $ lwork - nwork + 1, ierr )
1340 CALL dormbr(
'P',
'R',
'T', m, m, m, a, lda,
1341 $ work( itaup ), work( ivt ), ldwkvt,
1342 $ work( nwork ), lwork - nwork + 1, ierr )
1348 CALL dgemm(
'N',
'N', m, n, m, one, work( ivt ), ldwkvt,
1349 $ vt, ldvt, zero, a, lda )
1353 CALL dlacpy(
'F', m, n, a, lda, vt, ldvt )
1373 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1374 $ work( itaup ), work( nwork ), lwork-nwork+1,
1382 CALL dbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum, 1,
1383 $ dum, idum, work( nwork ), iwork, info )
1384 ELSE IF( wntqo )
THEN
1388 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1392 CALL dlaset(
'F', m, n, zero, zero, work( ivt ),
1394 nwork = ivt + ldwkvt*n
1401 nwork = ivt + ldwkvt*m
1406 chunk = ( lwork - m*m - 3*m ) / m
1414 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1415 $ work( ivt ), ldwkvt, dum, idum,
1416 $ work( nwork ), iwork, info )
1422 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1423 $ work( itauq ), u, ldu, work( nwork ),
1424 $ lwork - nwork + 1, ierr )
1426 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1433 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1434 $ work( itaup ), work( ivt ), ldwkvt,
1435 $ work( nwork ), lwork - nwork + 1, ierr )
1439 CALL dlacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
1447 CALL dorgbr(
'P', m, n, m, a, lda, work( itaup ),
1448 $ work( nwork ), lwork - nwork + 1, ierr )
1456 DO 40 i = 1, n, chunk
1457 blk = min( n - i + 1, chunk )
1458 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1459 $ ldwkvt, a( 1, i ), lda, zero,
1461 CALL dlacpy(
'F', m, blk, work( il ), m, a( 1, i ),
1465 ELSE IF( wntqs )
THEN
1473 CALL dlaset(
'F', m, n, zero, zero, vt, ldvt )
1474 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1475 $ ldvt, dum, idum, work( nwork ), iwork,
1483 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1484 $ work( itauq ), u, ldu, work( nwork ),
1485 $ lwork - nwork + 1, ierr )
1486 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1487 $ work( itaup ), vt, ldvt, work( nwork ),
1488 $ lwork - nwork + 1, ierr )
1489 ELSE IF( wntqa )
THEN
1497 CALL dlaset(
'F', n, n, zero, zero, vt, ldvt )
1498 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1499 $ ldvt, dum, idum, work( nwork ), iwork,
1505 CALL dlaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1514 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1515 $ work( itauq ), u, ldu, work( nwork ),
1516 $ lwork - nwork + 1, ierr )
1517 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1518 $ work( itaup ), vt, ldvt, work( nwork ),
1519 $ lwork - nwork + 1, ierr )
1528 IF( iscl.EQ.1 )
THEN
1529 IF( anrm.GT.bignum )
1530 $
CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1532 IF( anrm.LT.smlnum )
1533 $
CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
1539 work( 1 ) = droundup_lwork( maxwrk )
subroutine xerbla(srname, info)
subroutine dbdsdc(uplo, compq, n, d, e, u, ldu, vt, ldvt, q, iq, work, iwork, info)
DBDSDC
subroutine dgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
DGEBRD
subroutine dgelqf(m, n, a, lda, tau, work, lwork, info)
DGELQF
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dgeqrf(m, n, a, lda, tau, work, lwork, info)
DGEQRF
subroutine dgesdd(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, info)
DGESDD
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dorgbr(vect, m, n, k, a, lda, tau, work, lwork, info)
DORGBR
subroutine dorglq(m, n, k, a, lda, tau, work, lwork, info)
DORGLQ
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
subroutine dormbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
DORMBR