217 SUBROUTINE dgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
218 $ WORK, LWORK, IWORK, INFO )
227 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
231 DOUBLE PRECISION A( lda, * ), S( * ), U( ldu, * ),
232 $ vt( ldvt, * ), work( * )
238 DOUBLE PRECISION ZERO, ONE
239 parameter( zero = 0.0d0, one = 1.0d0 )
242 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
243 INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
244 $ ir, iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
245 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
246 $ mnthr, nwork, wrkbl
247 INTEGER LWORK_DGEBRD_MN, LWORK_DGEBRD_MM,
248 $ lwork_dgebrd_nn, lwork_dgelqf_mn,
250 $ lwork_dorgbr_p_mm, lwork_dorgbr_q_nn,
251 $ lwork_dorglq_mn, lwork_dorglq_nn,
252 $ lwork_dorgqr_mm, lwork_dorgqr_mn,
253 $ lwork_dormbr_prt_mm, lwork_dormbr_qln_mm,
254 $ lwork_dormbr_prt_mn, lwork_dormbr_qln_mn,
255 $ lwork_dormbr_prt_nn, lwork_dormbr_qln_nn
256 DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
260 DOUBLE PRECISION DUM( 1 )
268 LOGICAL LSAME, DISNAN
269 DOUBLE PRECISION DLAMCH, DLANGE, DROUNDUP_LWORK
270 EXTERNAL dlamch, dlange, lsame, disnan,
274 INTRINSIC int, max, min, sqrt
282 wntqa = lsame( jobz,
'A' )
283 wntqs = lsame( jobz,
'S' )
284 wntqas = wntqa .OR. wntqs
285 wntqo = lsame( jobz,
'O' )
286 wntqn = lsame( jobz,
'N' )
287 lquery = ( lwork.EQ.-1 )
289 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN 291 ELSE IF( m.LT.0 )
THEN 293 ELSE IF( n.LT.0 )
THEN 295 ELSE IF( lda.LT.max( 1, m ) )
THEN 297 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
298 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN 300 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
301 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
302 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN 317 mnthr = int( minmn*11.0d0 / 6.0d0 )
318 IF( m.GE.n .AND. minmn.GT.0 )
THEN 331 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
332 $ dum(1), dum(1), -1, ierr )
333 lwork_dgebrd_mn = int( dum(1) )
335 CALL dgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
336 $ dum(1), dum(1), -1, ierr )
337 lwork_dgebrd_nn = int( dum(1) )
339 CALL dgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
340 lwork_dgeqrf_mn = int( dum(1) )
342 CALL dorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
344 lwork_dorgbr_q_nn = int( dum(1) )
346 CALL dorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
347 lwork_dorgqr_mm = int( dum(1) )
349 CALL dorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
350 lwork_dorgqr_mn = int( dum(1) )
352 CALL dormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
353 $ dum(1), dum(1), n, dum(1), -1, ierr )
354 lwork_dormbr_prt_nn = int( dum(1) )
356 CALL dormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
357 $ dum(1), dum(1), n, dum(1), -1, ierr )
358 lwork_dormbr_qln_nn = int( dum(1) )
360 CALL dormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
361 $ dum(1), dum(1), m, dum(1), -1, ierr )
362 lwork_dormbr_qln_mn = int( dum(1) )
364 CALL dormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
365 $ dum(1), dum(1), m, dum(1), -1, ierr )
366 lwork_dormbr_qln_mm = int( dum(1) )
368 IF( m.GE.mnthr )
THEN 373 wrkbl = n + lwork_dgeqrf_mn
374 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
375 maxwrk = max( wrkbl, bdspac + n )
377 ELSE IF( wntqo )
THEN 381 wrkbl = n + lwork_dgeqrf_mn
382 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
383 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
384 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
385 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
386 wrkbl = max( wrkbl, 3*n + bdspac )
387 maxwrk = wrkbl + 2*n*n
388 minwrk = bdspac + 2*n*n + 3*n
389 ELSE IF( wntqs )
THEN 393 wrkbl = n + lwork_dgeqrf_mn
394 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
395 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
396 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
397 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
398 wrkbl = max( wrkbl, 3*n + bdspac )
400 minwrk = bdspac + n*n + 3*n
401 ELSE IF( wntqa )
THEN 405 wrkbl = n + lwork_dgeqrf_mn
406 wrkbl = max( wrkbl, n + lwork_dorgqr_mm )
407 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
408 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
409 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
410 wrkbl = max( wrkbl, 3*n + bdspac )
412 minwrk = n*n + max( 3*n + bdspac, n + m )
418 wrkbl = 3*n + lwork_dgebrd_mn
421 maxwrk = max( wrkbl, 3*n + bdspac )
422 minwrk = 3*n + max( m, bdspac )
423 ELSE IF( wntqo )
THEN 425 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
426 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
427 wrkbl = max( wrkbl, 3*n + bdspac )
429 minwrk = 3*n + max( m, n*n + bdspac )
430 ELSE IF( wntqs )
THEN 432 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
433 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
434 maxwrk = max( wrkbl, 3*n + bdspac )
435 minwrk = 3*n + max( m, bdspac )
436 ELSE IF( wntqa )
THEN 438 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mm )
439 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
440 maxwrk = max( wrkbl, 3*n + bdspac )
441 minwrk = 3*n + max( m, bdspac )
444 ELSE IF( minmn.GT.0 )
THEN 457 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
458 $ dum(1), dum(1), -1, ierr )
459 lwork_dgebrd_mn = int( dum(1) )
461 CALL dgebrd( m, m, a, m, s, dum(1), dum(1),
462 $ dum(1), dum(1), -1, ierr )
463 lwork_dgebrd_mm = int( dum(1) )
465 CALL dgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
466 lwork_dgelqf_mn = int( dum(1) )
468 CALL dorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
469 lwork_dorglq_nn = int( dum(1) )
471 CALL dorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
472 lwork_dorglq_mn = int( dum(1) )
474 CALL dorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
475 lwork_dorgbr_p_mm = int( dum(1) )
477 CALL dormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
478 $ dum(1), dum(1), m, dum(1), -1, ierr )
479 lwork_dormbr_prt_mm = int( dum(1) )
481 CALL dormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
482 $ dum(1), dum(1), m, dum(1), -1, ierr )
483 lwork_dormbr_prt_mn = int( dum(1) )
485 CALL dormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
486 $ dum(1), dum(1), n, dum(1), -1, ierr )
487 lwork_dormbr_prt_nn = int( dum(1) )
489 CALL dormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
490 $ dum(1), dum(1), m, dum(1), -1, ierr )
491 lwork_dormbr_qln_mm = int( dum(1) )
493 IF( n.GE.mnthr )
THEN 498 wrkbl = m + lwork_dgelqf_mn
499 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
500 maxwrk = max( wrkbl, bdspac + m )
502 ELSE IF( wntqo )
THEN 506 wrkbl = m + lwork_dgelqf_mn
507 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
508 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
509 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
510 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
511 wrkbl = max( wrkbl, 3*m + bdspac )
512 maxwrk = wrkbl + 2*m*m
513 minwrk = bdspac + 2*m*m + 3*m
514 ELSE IF( wntqs )
THEN 518 wrkbl = m + lwork_dgelqf_mn
519 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
520 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
521 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
522 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
523 wrkbl = max( wrkbl, 3*m + bdspac )
525 minwrk = bdspac + m*m + 3*m
526 ELSE IF( wntqa )
THEN 530 wrkbl = m + lwork_dgelqf_mn
531 wrkbl = max( wrkbl, m + lwork_dorglq_nn )
532 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
533 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
534 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
535 wrkbl = max( wrkbl, 3*m + bdspac )
537 minwrk = m*m + max( 3*m + bdspac, m + n )
543 wrkbl = 3*m + lwork_dgebrd_mn
546 maxwrk = max( wrkbl, 3*m + bdspac )
547 minwrk = 3*m + max( n, bdspac )
548 ELSE IF( wntqo )
THEN 550 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
551 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
552 wrkbl = max( wrkbl, 3*m + bdspac )
554 minwrk = 3*m + max( n, m*m + bdspac )
555 ELSE IF( wntqs )
THEN 557 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
558 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
559 maxwrk = max( wrkbl, 3*m + bdspac )
560 minwrk = 3*m + max( n, bdspac )
561 ELSE IF( wntqa )
THEN 563 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
564 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_nn )
565 maxwrk = max( wrkbl, 3*m + bdspac )
566 minwrk = 3*m + max( n, bdspac )
571 maxwrk = max( maxwrk, minwrk )
572 work( 1 ) = droundup_lwork( maxwrk )
574 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN 580 CALL xerbla(
'DGESDD', -info )
582 ELSE IF( lquery )
THEN 588 IF( m.EQ.0 .OR. n.EQ.0 )
THEN 595 smlnum = sqrt( dlamch(
'S' ) ) / eps
596 bignum = one / smlnum
600 anrm = dlange(
'M', m, n, a, lda, dum )
601 IF( disnan( anrm ) )
THEN 606 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 608 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
609 ELSE IF( anrm.GT.bignum )
THEN 611 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
620 IF( m.GE.mnthr )
THEN 634 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
635 $ lwork - nwork + 1, ierr )
639 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
649 CALL dgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
650 $ work( itaup ), work( nwork ), lwork-nwork+1,
657 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
658 $ dum, idum, work( nwork ), iwork, info )
660 ELSE IF( wntqo )
THEN 670 IF( lwork .GE. lda*n + n*n + 3*n + bdspac )
THEN 673 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
682 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
683 $ lwork - nwork + 1, ierr )
687 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
688 CALL dlaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
695 CALL dorgqr( m, n, n, a, lda, work( itau ),
696 $ work( nwork ), lwork - nwork + 1, ierr )
706 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
707 $ work( itauq ), work( itaup ), work( nwork ),
708 $ lwork - nwork + 1, ierr )
720 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
721 $ vt, ldvt, dum, idum, work( nwork ), iwork,
729 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
730 $ work( itauq ), work( iu ), n, work( nwork ),
731 $ lwork - nwork + 1, ierr )
732 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
733 $ work( itaup ), vt, ldvt, work( nwork ),
734 $ lwork - nwork + 1, ierr )
741 DO 10 i = 1, m, ldwrkr
742 chunk = min( m - i + 1, ldwrkr )
743 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
744 $ lda, work( iu ), n, zero, work( ir ),
746 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
750 ELSE IF( wntqs )
THEN 768 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
769 $ lwork - nwork + 1, ierr )
773 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
774 CALL dlaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
781 CALL dorgqr( m, n, n, a, lda, work( itau ),
782 $ work( nwork ), lwork - nwork + 1, ierr )
792 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
793 $ work( itauq ), work( itaup ), work( nwork ),
794 $ lwork - nwork + 1, ierr )
801 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
802 $ ldvt, dum, idum, work( nwork ), iwork,
810 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
811 $ work( itauq ), u, ldu, work( nwork ),
812 $ lwork - nwork + 1, ierr )
814 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
815 $ work( itaup ), vt, ldvt, work( nwork ),
816 $ lwork - nwork + 1, ierr )
822 CALL dlacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
823 CALL dgemm(
'N',
'N', m, n, n, one, a, lda, work( ir ),
824 $ ldwrkr, zero, u, ldu )
826 ELSE IF( wntqa )
THEN 844 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
845 $ lwork - nwork + 1, ierr )
846 CALL dlacpy(
'L', m, n, a, lda, u, ldu )
851 CALL dorgqr( m, m, n, u, ldu, work( itau ),
852 $ work( nwork ), lwork - nwork + 1, ierr )
856 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
866 CALL dgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
867 $ work( itaup ), work( nwork ), lwork-nwork+1,
875 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
876 $ vt, ldvt, dum, idum, work( nwork ), iwork,
884 CALL dormbr(
'Q',
'L',
'N', n, n, n, a, lda,
885 $ work( itauq ), work( iu ), ldwrku,
886 $ work( nwork ), lwork - nwork + 1, ierr )
887 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
888 $ work( itaup ), vt, ldvt, work( nwork ),
889 $ lwork - nwork + 1, ierr )
895 CALL dgemm(
'N',
'N', m, n, n, one, u, ldu, work( iu ),
896 $ ldwrku, zero, a, lda )
900 CALL dlacpy(
'F', m, n, a, lda, u, ldu )
920 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
921 $ work( itaup ), work( nwork ), lwork-nwork+1,
929 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
930 $ dum, idum, work( nwork ), iwork, info )
931 ELSE IF( wntqo )
THEN 934 IF( lwork .GE. m*n + 3*n + bdspac )
THEN 939 nwork = iu + ldwrku*n
940 CALL dlaset(
'F', m, n, zero, zero, work( iu ),
949 nwork = iu + ldwrku*n
954 ldwrkr = ( lwork - n*n - 3*n ) / n
956 nwork = iu + ldwrku*n
963 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
964 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
971 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
972 $ work( itaup ), vt, ldvt, work( nwork ),
973 $ lwork - nwork + 1, ierr )
975 IF( lwork .GE. m*n + 3*n + bdspac )
THEN 982 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
983 $ work( itauq ), work( iu ), ldwrku,
984 $ work( nwork ), lwork - nwork + 1, ierr )
988 CALL dlacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
996 CALL dorgbr(
'Q', m, n, n, a, lda, work( itauq ),
997 $ work( nwork ), lwork - nwork + 1, ierr )
1005 DO 20 i = 1, m, ldwrkr
1006 chunk = min( m - i + 1, ldwrkr )
1007 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
1008 $ lda, work( iu ), ldwrku, zero,
1009 $ work( ir ), ldwrkr )
1010 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
1015 ELSE IF( wntqs )
THEN 1023 CALL dlaset(
'F', m, n, zero, zero, u, ldu )
1024 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1025 $ ldvt, dum, idum, work( nwork ), iwork,
1033 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1034 $ work( itauq ), u, ldu, work( nwork ),
1035 $ lwork - nwork + 1, ierr )
1036 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
1037 $ work( itaup ), vt, ldvt, work( nwork ),
1038 $ lwork - nwork + 1, ierr )
1039 ELSE IF( wntqa )
THEN 1047 CALL dlaset(
'F', m, m, zero, zero, u, ldu )
1048 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1049 $ ldvt, dum, idum, work( nwork ), iwork,
1055 CALL dlaset(
'F', m - n, m - n, zero, one, u(n+1,n+1),
1064 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1065 $ work( itauq ), u, ldu, work( nwork ),
1066 $ lwork - nwork + 1, ierr )
1067 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1068 $ work( itaup ), vt, ldvt, work( nwork ),
1069 $ lwork - nwork + 1, ierr )
1080 IF( n.GE.mnthr )
THEN 1094 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1095 $ lwork - nwork + 1, ierr )
1099 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1109 CALL dgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1110 $ work( itaup ), work( nwork ), lwork-nwork+1,
1117 CALL dbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum, 1,
1118 $ dum, idum, work( nwork ), iwork, info )
1120 ELSE IF( wntqo )
THEN 1132 IF( lwork .GE. m*n + m*m + 3*m + bdspac )
THEN 1137 chunk = ( lwork - m*m ) / m
1139 itau = il + ldwrkl*m
1146 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1147 $ lwork - nwork + 1, ierr )
1151 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1152 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1153 $ work( il + ldwrkl ), ldwrkl )
1159 CALL dorglq( m, n, m, a, lda, work( itau ),
1160 $ work( nwork ), lwork - nwork + 1, ierr )
1170 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1171 $ work( itauq ), work( itaup ), work( nwork ),
1172 $ lwork - nwork + 1, ierr )
1179 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1180 $ work( ivt ), m, dum, idum, work( nwork ),
1188 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1189 $ work( itauq ), u, ldu, work( nwork ),
1190 $ lwork - nwork + 1, ierr )
1191 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1192 $ work( itaup ), work( ivt ), m,
1193 $ work( nwork ), lwork - nwork + 1, ierr )
1201 DO 30 i = 1, n, chunk
1202 blk = min( n - i + 1, chunk )
1203 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ), m,
1204 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1205 CALL dlacpy(
'F', m, blk, work( il ), ldwrkl,
1209 ELSE IF( wntqs )
THEN 1220 itau = il + ldwrkl*m
1227 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1228 $ lwork - nwork + 1, ierr )
1232 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1233 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1234 $ work( il + ldwrkl ), ldwrkl )
1240 CALL dorglq( m, n, m, a, lda, work( itau ),
1241 $ work( nwork ), lwork - nwork + 1, ierr )
1251 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1252 $ work( itauq ), work( itaup ), work( nwork ),
1253 $ lwork - nwork + 1, ierr )
1260 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1261 $ ldvt, dum, idum, work( nwork ), iwork,
1269 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1270 $ work( itauq ), u, ldu, work( nwork ),
1271 $ lwork - nwork + 1, ierr )
1272 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1273 $ work( itaup ), vt, ldvt, work( nwork ),
1274 $ lwork - nwork + 1, ierr )
1280 CALL dlacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1281 CALL dgemm(
'N',
'N', m, n, m, one, work( il ), ldwrkl,
1282 $ a, lda, zero, vt, ldvt )
1284 ELSE IF( wntqa )
THEN 1295 itau = ivt + ldwkvt*m
1302 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1303 $ lwork - nwork + 1, ierr )
1304 CALL dlacpy(
'U', m, n, a, lda, vt, ldvt )
1310 CALL dorglq( n, n, m, vt, ldvt, work( itau ),
1311 $ work( nwork ), lwork - nwork + 1, ierr )
1315 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1325 CALL dgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1326 $ work( itaup ), work( nwork ), lwork-nwork+1,
1334 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1335 $ work( ivt ), ldwkvt, dum, idum,
1336 $ work( nwork ), iwork, info )
1343 CALL dormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1344 $ work( itauq ), u, ldu, work( nwork ),
1345 $ lwork - nwork + 1, ierr )
1346 CALL dormbr(
'P',
'R',
'T', m, m, m, a, lda,
1347 $ work( itaup ), work( ivt ), ldwkvt,
1348 $ work( nwork ), lwork - nwork + 1, ierr )
1354 CALL dgemm(
'N',
'N', m, n, m, one, work( ivt ), ldwkvt,
1355 $ vt, ldvt, zero, a, lda )
1359 CALL dlacpy(
'F', m, n, a, lda, vt, ldvt )
1379 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1380 $ work( itaup ), work( nwork ), lwork-nwork+1,
1388 CALL dbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum, 1,
1389 $ dum, idum, work( nwork ), iwork, info )
1390 ELSE IF( wntqo )
THEN 1394 IF( lwork .GE. m*n + 3*m + bdspac )
THEN 1398 CALL dlaset(
'F', m, n, zero, zero, work( ivt ),
1400 nwork = ivt + ldwkvt*n
1407 nwork = ivt + ldwkvt*m
1412 chunk = ( lwork - m*m - 3*m ) / m
1420 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1421 $ work( ivt ), ldwkvt, dum, idum,
1422 $ work( nwork ), iwork, info )
1428 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1429 $ work( itauq ), u, ldu, work( nwork ),
1430 $ lwork - nwork + 1, ierr )
1432 IF( lwork .GE. m*n + 3*m + bdspac )
THEN 1439 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1440 $ work( itaup ), work( ivt ), ldwkvt,
1441 $ work( nwork ), lwork - nwork + 1, ierr )
1445 CALL dlacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
1453 CALL dorgbr(
'P', m, n, m, a, lda, work( itaup ),
1454 $ work( nwork ), lwork - nwork + 1, ierr )
1462 DO 40 i = 1, n, chunk
1463 blk = min( n - i + 1, chunk )
1464 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1465 $ ldwkvt, a( 1, i ), lda, zero,
1467 CALL dlacpy(
'F', m, blk, work( il ), m, a( 1, i ),
1471 ELSE IF( wntqs )
THEN 1479 CALL dlaset(
'F', m, n, zero, zero, vt, ldvt )
1480 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1481 $ ldvt, dum, idum, work( nwork ), iwork,
1489 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1490 $ work( itauq ), u, ldu, work( nwork ),
1491 $ lwork - nwork + 1, ierr )
1492 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1493 $ work( itaup ), vt, ldvt, work( nwork ),
1494 $ lwork - nwork + 1, ierr )
1495 ELSE IF( wntqa )
THEN 1503 CALL dlaset(
'F', n, n, zero, zero, vt, ldvt )
1504 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1505 $ ldvt, dum, idum, work( nwork ), iwork,
1511 CALL dlaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1520 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1521 $ work( itauq ), u, ldu, work( nwork ),
1522 $ lwork - nwork + 1, ierr )
1523 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1524 $ work( itaup ), vt, ldvt, work( nwork ),
1525 $ lwork - nwork + 1, ierr )
1534 IF( iscl.EQ.1 )
THEN 1535 IF( anrm.GT.bignum )
1536 $
CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1538 IF( anrm.LT.smlnum )
1539 $
CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
1545 work( 1 ) = droundup_lwork( maxwrk )
subroutine dgesdd(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)
DGESDD
subroutine dgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
DGEBRD
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine dbdsdc(UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ, WORK, IWORK, INFO)
DBDSDC
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
subroutine dorgbr(VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGBR
subroutine dgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGELQF
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 dorglq(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGLQ
subroutine dgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGEQRF