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 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 dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
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 xerbla(SRNAME, INFO)
XERBLA
subroutine dbdsdc(UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ, WORK, IWORK, INFO)
DBDSDC
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine dorgbr(VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGBR
subroutine dgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGEQRF
subroutine dgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGELQF
subroutine dgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
DGEBRD
subroutine dgesdd(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)
DGESDD
subroutine dorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGQR
subroutine dorglq(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGLQ
subroutine dormbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMBR