219 SUBROUTINE dgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
220 $ work, lwork, iwork, info )
230 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
234 DOUBLE PRECISION A( lda, * ), S( * ), U( ldu, * ),
235 $ vt( ldvt, * ), work( * )
241 DOUBLE PRECISION ZERO, ONE
242 parameter ( zero = 0.0d0, one = 1.0d0 )
245 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
246 INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
247 $ ir, iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
248 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
249 $ mnthr, nwork, wrkbl
250 INTEGER LWORK_DGEBRD_MN, LWORK_DGEBRD_MM,
251 $ lwork_dgebrd_nn, lwork_dgelqf_mn,
253 $ lwork_dorgbr_p_mm, lwork_dorgbr_q_nn,
254 $ lwork_dorglq_mn, lwork_dorglq_nn,
255 $ lwork_dorgqr_mm, lwork_dorgqr_mn,
256 $ lwork_dormbr_prt_mm, lwork_dormbr_qln_mm,
257 $ lwork_dormbr_prt_mn, lwork_dormbr_qln_mn,
258 $ lwork_dormbr_prt_nn, lwork_dormbr_qln_nn
259 DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
263 DOUBLE PRECISION DUM( 1 )
272 DOUBLE PRECISION DLAMCH, DLANGE
273 EXTERNAL dlamch, dlange, lsame
276 INTRINSIC int, max, min, sqrt
284 wntqa = lsame( jobz,
'A' )
285 wntqs = lsame( jobz,
'S' )
286 wntqas = wntqa .OR. wntqs
287 wntqo = lsame( jobz,
'O' )
288 wntqn = lsame( jobz,
'N' )
289 lquery = ( lwork.EQ.-1 )
291 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
293 ELSE IF( m.LT.0 )
THEN
295 ELSE IF( n.LT.0 )
THEN
297 ELSE IF( lda.LT.max( 1, m ) )
THEN
299 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
300 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
302 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
303 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
304 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
319 mnthr = int( minmn*11.0d0 / 6.0d0 )
320 IF( m.GE.n .AND. minmn.GT.0 )
THEN
333 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
334 $ dum(1), dum(1), -1, ierr )
335 lwork_dgebrd_mn = int( dum(1) )
337 CALL dgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
338 $ dum(1), dum(1), -1, ierr )
339 lwork_dgebrd_nn = int( dum(1) )
341 CALL dgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
342 lwork_dgeqrf_mn = int( dum(1) )
344 CALL dorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
346 lwork_dorgbr_q_nn = int( dum(1) )
348 CALL dorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
349 lwork_dorgqr_mm = int( dum(1) )
351 CALL dorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
352 lwork_dorgqr_mn = int( dum(1) )
354 CALL dormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
355 $ dum(1), dum(1), n, dum(1), -1, ierr )
356 lwork_dormbr_prt_nn = int( dum(1) )
358 CALL dormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
359 $ dum(1), dum(1), n, dum(1), -1, ierr )
360 lwork_dormbr_qln_nn = int( dum(1) )
362 CALL dormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
363 $ dum(1), dum(1), m, dum(1), -1, ierr )
364 lwork_dormbr_qln_mn = int( dum(1) )
366 CALL dormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
367 $ dum(1), dum(1), m, dum(1), -1, ierr )
368 lwork_dormbr_qln_mm = int( dum(1) )
370 IF( m.GE.mnthr )
THEN
375 wrkbl = n + lwork_dgeqrf_mn
376 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
377 maxwrk = max( wrkbl, bdspac + n )
379 ELSE IF( wntqo )
THEN
383 wrkbl = n + lwork_dgeqrf_mn
384 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
385 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
386 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
387 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
388 wrkbl = max( wrkbl, 3*n + bdspac )
389 maxwrk = wrkbl + 2*n*n
390 minwrk = bdspac + 2*n*n + 3*n
391 ELSE IF( wntqs )
THEN
395 wrkbl = n + lwork_dgeqrf_mn
396 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
397 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
398 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
399 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
400 wrkbl = max( wrkbl, 3*n + bdspac )
402 minwrk = bdspac + n*n + 3*n
403 ELSE IF( wntqa )
THEN
407 wrkbl = n + lwork_dgeqrf_mn
408 wrkbl = max( wrkbl, n + lwork_dorgqr_mm )
409 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
410 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
411 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
412 wrkbl = max( wrkbl, 3*n + bdspac )
414 minwrk = n*n + max( 3*n + bdspac, n + m )
420 wrkbl = 3*n + lwork_dgebrd_mn
423 maxwrk = max( wrkbl, 3*n + bdspac )
424 minwrk = 3*n + max( m, bdspac )
425 ELSE IF( wntqo )
THEN
427 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
428 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
429 wrkbl = max( wrkbl, 3*n + bdspac )
431 minwrk = 3*n + max( m, n*n + bdspac )
432 ELSE IF( wntqs )
THEN
434 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
435 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
436 maxwrk = max( wrkbl, 3*n + bdspac )
437 minwrk = 3*n + max( m, bdspac )
438 ELSE IF( wntqa )
THEN
440 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mm )
441 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
442 maxwrk = max( wrkbl, 3*n + bdspac )
443 minwrk = 3*n + max( m, bdspac )
446 ELSE IF( minmn.GT.0 )
THEN
459 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
460 $ dum(1), dum(1), -1, ierr )
461 lwork_dgebrd_mn = int( dum(1) )
463 CALL dgebrd( m, m, a, m, s, dum(1), dum(1),
464 $ dum(1), dum(1), -1, ierr )
465 lwork_dgebrd_mm = int( dum(1) )
467 CALL dgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
468 lwork_dgelqf_mn = int( dum(1) )
470 CALL dorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
471 lwork_dorglq_nn = int( dum(1) )
473 CALL dorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
474 lwork_dorglq_mn = int( dum(1) )
476 CALL dorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
477 lwork_dorgbr_p_mm = int( dum(1) )
479 CALL dormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
480 $ dum(1), dum(1), m, dum(1), -1, ierr )
481 lwork_dormbr_prt_mm = int( dum(1) )
483 CALL dormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
484 $ dum(1), dum(1), m, dum(1), -1, ierr )
485 lwork_dormbr_prt_mn = int( dum(1) )
487 CALL dormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
488 $ dum(1), dum(1), n, dum(1), -1, ierr )
489 lwork_dormbr_prt_nn = int( dum(1) )
491 CALL dormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
492 $ dum(1), dum(1), m, dum(1), -1, ierr )
493 lwork_dormbr_qln_mm = int( dum(1) )
495 IF( n.GE.mnthr )
THEN
500 wrkbl = m + lwork_dgelqf_mn
501 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
502 maxwrk = max( wrkbl, bdspac + m )
504 ELSE IF( wntqo )
THEN
508 wrkbl = m + lwork_dgelqf_mn
509 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
510 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
511 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
512 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
513 wrkbl = max( wrkbl, 3*m + bdspac )
514 maxwrk = wrkbl + 2*m*m
515 minwrk = bdspac + 2*m*m + 3*m
516 ELSE IF( wntqs )
THEN
520 wrkbl = m + lwork_dgelqf_mn
521 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
522 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
523 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
524 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
525 wrkbl = max( wrkbl, 3*m + bdspac )
527 minwrk = bdspac + m*m + 3*m
528 ELSE IF( wntqa )
THEN
532 wrkbl = m + lwork_dgelqf_mn
533 wrkbl = max( wrkbl, m + lwork_dorglq_nn )
534 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
535 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
536 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
537 wrkbl = max( wrkbl, 3*m + bdspac )
539 minwrk = m*m + max( 3*m + bdspac, m + n )
545 wrkbl = 3*m + lwork_dgebrd_mn
548 maxwrk = max( wrkbl, 3*m + bdspac )
549 minwrk = 3*m + max( n, bdspac )
550 ELSE IF( wntqo )
THEN
552 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
553 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
554 wrkbl = max( wrkbl, 3*m + bdspac )
556 minwrk = 3*m + max( n, m*m + bdspac )
557 ELSE IF( wntqs )
THEN
559 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
560 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
561 maxwrk = max( wrkbl, 3*m + bdspac )
562 minwrk = 3*m + max( n, bdspac )
563 ELSE IF( wntqa )
THEN
565 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
566 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_nn )
567 maxwrk = max( wrkbl, 3*m + bdspac )
568 minwrk = 3*m + max( n, bdspac )
573 maxwrk = max( maxwrk, minwrk )
576 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
582 CALL xerbla(
'DGESDD', -info )
584 ELSE IF( lquery )
THEN
590 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
597 smlnum = sqrt( dlamch(
'S' ) ) / eps
598 bignum = one / smlnum
602 anrm = dlange(
'M', m, n, a, lda, dum )
604 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
606 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
607 ELSE IF( anrm.GT.bignum )
THEN
609 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
618 IF( m.GE.mnthr )
THEN
632 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
633 $ lwork - nwork + 1, ierr )
637 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
647 CALL dgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
648 $ work( itaup ), work( nwork ), lwork-nwork+1,
655 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
656 $ dum, idum, work( nwork ), iwork, info )
658 ELSE IF( wntqo )
THEN
668 IF( lwork .GE. lda*n + n*n + 3*n + bdspac )
THEN
671 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
680 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
681 $ lwork - nwork + 1, ierr )
685 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
686 CALL dlaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
693 CALL dorgqr( m, n, n, a, lda, work( itau ),
694 $ work( nwork ), lwork - nwork + 1, ierr )
704 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
705 $ work( itauq ), work( itaup ), work( nwork ),
706 $ lwork - nwork + 1, ierr )
718 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
719 $ vt, ldvt, dum, idum, work( nwork ), iwork,
727 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
728 $ work( itauq ), work( iu ), n, work( nwork ),
729 $ lwork - nwork + 1, ierr )
730 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
731 $ work( itaup ), vt, ldvt, work( nwork ),
732 $ lwork - nwork + 1, ierr )
739 DO 10 i = 1, m, ldwrkr
740 chunk = min( m - i + 1, ldwrkr )
741 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
742 $ lda, work( iu ), n, zero, work( ir ),
744 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
748 ELSE IF( wntqs )
THEN
766 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
767 $ lwork - nwork + 1, ierr )
771 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
772 CALL dlaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
779 CALL dorgqr( m, n, n, a, lda, work( itau ),
780 $ work( nwork ), lwork - nwork + 1, ierr )
790 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
791 $ work( itauq ), work( itaup ), work( nwork ),
792 $ lwork - nwork + 1, ierr )
799 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
800 $ ldvt, dum, idum, work( nwork ), iwork,
808 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
809 $ work( itauq ), u, ldu, work( nwork ),
810 $ lwork - nwork + 1, ierr )
812 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
813 $ work( itaup ), vt, ldvt, work( nwork ),
814 $ lwork - nwork + 1, ierr )
820 CALL dlacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
821 CALL dgemm(
'N',
'N', m, n, n, one, a, lda, work( ir ),
822 $ ldwrkr, zero, u, ldu )
824 ELSE IF( wntqa )
THEN
842 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
843 $ lwork - nwork + 1, ierr )
844 CALL dlacpy(
'L', m, n, a, lda, u, ldu )
849 CALL dorgqr( m, m, n, u, ldu, work( itau ),
850 $ work( nwork ), lwork - nwork + 1, ierr )
854 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
864 CALL dgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
865 $ work( itaup ), work( nwork ), lwork-nwork+1,
873 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
874 $ vt, ldvt, dum, idum, work( nwork ), iwork,
882 CALL dormbr(
'Q',
'L',
'N', n, n, n, a, lda,
883 $ work( itauq ), work( iu ), ldwrku,
884 $ work( nwork ), lwork - nwork + 1, ierr )
885 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
886 $ work( itaup ), vt, ldvt, work( nwork ),
887 $ lwork - nwork + 1, ierr )
893 CALL dgemm(
'N',
'N', m, n, n, one, u, ldu, work( iu ),
894 $ ldwrku, zero, a, lda )
898 CALL dlacpy(
'F', m, n, a, lda, u, ldu )
918 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
919 $ work( itaup ), work( nwork ), lwork-nwork+1,
927 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
928 $ dum, idum, work( nwork ), iwork, info )
929 ELSE IF( wntqo )
THEN
932 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
937 nwork = iu + ldwrku*n
938 CALL dlaset(
'F', m, n, zero, zero, work( iu ),
947 nwork = iu + ldwrku*n
952 ldwrkr = ( lwork - n*n - 3*n ) / n
954 nwork = iu + ldwrku*n
961 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
962 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
969 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
970 $ work( itaup ), vt, ldvt, work( nwork ),
971 $ lwork - nwork + 1, ierr )
973 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
980 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
981 $ work( itauq ), work( iu ), ldwrku,
982 $ work( nwork ), lwork - nwork + 1, ierr )
986 CALL dlacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
994 CALL dorgbr(
'Q', m, n, n, a, lda, work( itauq ),
995 $ work( nwork ), lwork - nwork + 1, ierr )
1003 DO 20 i = 1, m, ldwrkr
1004 chunk = min( m - i + 1, ldwrkr )
1005 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
1006 $ lda, work( iu ), ldwrku, zero,
1007 $ work( ir ), ldwrkr )
1008 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
1013 ELSE IF( wntqs )
THEN
1021 CALL dlaset(
'F', m, n, zero, zero, u, ldu )
1022 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1023 $ ldvt, dum, idum, work( nwork ), iwork,
1031 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1032 $ work( itauq ), u, ldu, work( nwork ),
1033 $ lwork - nwork + 1, ierr )
1034 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
1035 $ work( itaup ), vt, ldvt, work( nwork ),
1036 $ lwork - nwork + 1, ierr )
1037 ELSE IF( wntqa )
THEN
1045 CALL dlaset(
'F', m, m, zero, zero, u, ldu )
1046 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1047 $ ldvt, dum, idum, work( nwork ), iwork,
1053 CALL dlaset(
'F', m - n, m - n, zero, one, u(n+1,n+1),
1062 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1063 $ work( itauq ), u, ldu, work( nwork ),
1064 $ lwork - nwork + 1, ierr )
1065 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1066 $ work( itaup ), vt, ldvt, work( nwork ),
1067 $ lwork - nwork + 1, ierr )
1078 IF( n.GE.mnthr )
THEN
1092 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1093 $ lwork - nwork + 1, ierr )
1097 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1107 CALL dgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1108 $ work( itaup ), work( nwork ), lwork-nwork+1,
1115 CALL dbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum, 1,
1116 $ dum, idum, work( nwork ), iwork, info )
1118 ELSE IF( wntqo )
THEN
1130 IF( lwork .GE. m*n + m*m + 3*m + bdspac )
THEN
1135 chunk = ( lwork - m*m ) / m
1137 itau = il + ldwrkl*m
1144 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1145 $ lwork - nwork + 1, ierr )
1149 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1150 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1151 $ work( il + ldwrkl ), ldwrkl )
1157 CALL dorglq( m, n, m, a, lda, work( itau ),
1158 $ work( nwork ), lwork - nwork + 1, ierr )
1168 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1169 $ work( itauq ), work( itaup ), work( nwork ),
1170 $ lwork - nwork + 1, ierr )
1177 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1178 $ work( ivt ), m, dum, idum, work( nwork ),
1186 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1187 $ work( itauq ), u, ldu, work( nwork ),
1188 $ lwork - nwork + 1, ierr )
1189 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1190 $ work( itaup ), work( ivt ), m,
1191 $ work( nwork ), lwork - nwork + 1, ierr )
1199 DO 30 i = 1, n, chunk
1200 blk = min( n - i + 1, chunk )
1201 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ), m,
1202 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1203 CALL dlacpy(
'F', m, blk, work( il ), ldwrkl,
1207 ELSE IF( wntqs )
THEN
1218 itau = il + ldwrkl*m
1225 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1226 $ lwork - nwork + 1, ierr )
1230 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1231 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1232 $ work( il + ldwrkl ), ldwrkl )
1238 CALL dorglq( m, n, m, a, lda, work( itau ),
1239 $ work( nwork ), lwork - nwork + 1, ierr )
1249 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1250 $ work( itauq ), work( itaup ), work( nwork ),
1251 $ lwork - nwork + 1, ierr )
1258 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1259 $ ldvt, dum, idum, work( nwork ), iwork,
1267 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1268 $ work( itauq ), u, ldu, work( nwork ),
1269 $ lwork - nwork + 1, ierr )
1270 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1271 $ work( itaup ), vt, ldvt, work( nwork ),
1272 $ lwork - nwork + 1, ierr )
1278 CALL dlacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1279 CALL dgemm(
'N',
'N', m, n, m, one, work( il ), ldwrkl,
1280 $ a, lda, zero, vt, ldvt )
1282 ELSE IF( wntqa )
THEN
1293 itau = ivt + ldwkvt*m
1300 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1301 $ lwork - nwork + 1, ierr )
1302 CALL dlacpy(
'U', m, n, a, lda, vt, ldvt )
1308 CALL dorglq( n, n, m, vt, ldvt, work( itau ),
1309 $ work( nwork ), lwork - nwork + 1, ierr )
1313 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1323 CALL dgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1324 $ work( itaup ), work( nwork ), lwork-nwork+1,
1332 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1333 $ work( ivt ), ldwkvt, dum, idum,
1334 $ work( nwork ), iwork, info )
1341 CALL dormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1342 $ work( itauq ), u, ldu, work( nwork ),
1343 $ lwork - nwork + 1, ierr )
1344 CALL dormbr(
'P',
'R',
'T', m, m, m, a, lda,
1345 $ work( itaup ), work( ivt ), ldwkvt,
1346 $ work( nwork ), lwork - nwork + 1, ierr )
1352 CALL dgemm(
'N',
'N', m, n, m, one, work( ivt ), ldwkvt,
1353 $ vt, ldvt, zero, a, lda )
1357 CALL dlacpy(
'F', m, n, a, lda, vt, ldvt )
1377 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1378 $ work( itaup ), work( nwork ), lwork-nwork+1,
1386 CALL dbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum, 1,
1387 $ dum, idum, work( nwork ), iwork, info )
1388 ELSE IF( wntqo )
THEN
1392 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1396 CALL dlaset(
'F', m, n, zero, zero, work( ivt ),
1398 nwork = ivt + ldwkvt*n
1405 nwork = ivt + ldwkvt*m
1410 chunk = ( lwork - m*m - 3*m ) / m
1418 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1419 $ work( ivt ), ldwkvt, dum, idum,
1420 $ work( nwork ), iwork, info )
1426 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1427 $ work( itauq ), u, ldu, work( nwork ),
1428 $ lwork - nwork + 1, ierr )
1430 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1437 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1438 $ work( itaup ), work( ivt ), ldwkvt,
1439 $ work( nwork ), lwork - nwork + 1, ierr )
1443 CALL dlacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
1451 CALL dorgbr(
'P', m, n, m, a, lda, work( itaup ),
1452 $ work( nwork ), lwork - nwork + 1, ierr )
1460 DO 40 i = 1, n, chunk
1461 blk = min( n - i + 1, chunk )
1462 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1463 $ ldwkvt, a( 1, i ), lda, zero,
1465 CALL dlacpy(
'F', m, blk, work( il ), m, a( 1, i ),
1469 ELSE IF( wntqs )
THEN
1477 CALL dlaset(
'F', m, n, zero, zero, vt, ldvt )
1478 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1479 $ ldvt, dum, idum, work( nwork ), iwork,
1487 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1488 $ work( itauq ), u, ldu, work( nwork ),
1489 $ lwork - nwork + 1, ierr )
1490 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1491 $ work( itaup ), vt, ldvt, work( nwork ),
1492 $ lwork - nwork + 1, ierr )
1493 ELSE IF( wntqa )
THEN
1501 CALL dlaset(
'F', n, n, zero, zero, vt, ldvt )
1502 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1503 $ ldvt, dum, idum, work( nwork ), iwork,
1509 CALL dlaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1518 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1519 $ work( itauq ), u, ldu, work( nwork ),
1520 $ lwork - nwork + 1, ierr )
1521 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1522 $ work( itaup ), vt, ldvt, work( nwork ),
1523 $ lwork - nwork + 1, ierr )
1532 IF( iscl.EQ.1 )
THEN
1533 IF( anrm.GT.bignum )
1534 $
CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1536 IF( anrm.LT.smlnum )
1537 $
CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
subroutine dgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
DGEBRD
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 dormbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMBR
subroutine dorglq(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGLQ
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 dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine dgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGELQF
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dgesdd(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)
DGESDD
subroutine dorgbr(VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGBR
subroutine dbdsdc(UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ, WORK, IWORK, INFO)
DBDSDC
subroutine dgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DGEQRF
subroutine dorgqr(M, N, K, A, LDA, TAU, WORK, LWORK, INFO)
DORGQR