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
273 INTRINSIC int, max, min, sqrt
281 wntqa =
lsame( jobz,
'A' )
282 wntqs =
lsame( jobz,
'S' )
283 wntqas = wntqa .OR. wntqs
284 wntqo =
lsame( jobz,
'O' )
285 wntqn =
lsame( jobz,
'N' )
286 lquery = ( lwork.EQ.-1 )
288 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
290 ELSE IF( m.LT.0 )
THEN
292 ELSE IF( n.LT.0 )
THEN
294 ELSE IF( lda.LT.max( 1, m ) )
THEN
296 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
297 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
299 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
300 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
301 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
316 mnthr = int( minmn*11.0d0 / 6.0d0 )
317 IF( m.GE.n .AND. minmn.GT.0 )
THEN
330 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
331 $ dum(1), dum(1), -1, ierr )
332 lwork_dgebrd_mn = int( dum(1) )
334 CALL dgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
335 $ dum(1), dum(1), -1, ierr )
336 lwork_dgebrd_nn = int( dum(1) )
338 CALL dgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
339 lwork_dgeqrf_mn = int( dum(1) )
341 CALL dorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
343 lwork_dorgbr_q_nn = int( dum(1) )
345 CALL dorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
346 lwork_dorgqr_mm = int( dum(1) )
348 CALL dorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
349 lwork_dorgqr_mn = int( dum(1) )
351 CALL dormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
352 $ dum(1), dum(1), n, dum(1), -1, ierr )
353 lwork_dormbr_prt_nn = int( dum(1) )
355 CALL dormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
356 $ dum(1), dum(1), n, dum(1), -1, ierr )
357 lwork_dormbr_qln_nn = int( dum(1) )
359 CALL dormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
360 $ dum(1), dum(1), m, dum(1), -1, ierr )
361 lwork_dormbr_qln_mn = int( dum(1) )
363 CALL dormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
364 $ dum(1), dum(1), m, dum(1), -1, ierr )
365 lwork_dormbr_qln_mm = int( dum(1) )
367 IF( m.GE.mnthr )
THEN
372 wrkbl = n + lwork_dgeqrf_mn
373 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
374 maxwrk = max( wrkbl, bdspac + n )
376 ELSE IF( wntqo )
THEN
380 wrkbl = n + lwork_dgeqrf_mn
381 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
382 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
383 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
384 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
385 wrkbl = max( wrkbl, 3*n + bdspac )
386 maxwrk = wrkbl + 2*n*n
387 minwrk = bdspac + 2*n*n + 3*n
388 ELSE IF( wntqs )
THEN
392 wrkbl = n + lwork_dgeqrf_mn
393 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
394 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
395 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
396 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
397 wrkbl = max( wrkbl, 3*n + bdspac )
399 minwrk = bdspac + n*n + 3*n
400 ELSE IF( wntqa )
THEN
404 wrkbl = n + lwork_dgeqrf_mn
405 wrkbl = max( wrkbl, n + lwork_dorgqr_mm )
406 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
407 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
408 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
409 wrkbl = max( wrkbl, 3*n + bdspac )
411 minwrk = n*n + max( 3*n + bdspac, n + m )
417 wrkbl = 3*n + lwork_dgebrd_mn
420 maxwrk = max( wrkbl, 3*n + bdspac )
421 minwrk = 3*n + max( m, bdspac )
422 ELSE IF( wntqo )
THEN
424 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
425 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
426 wrkbl = max( wrkbl, 3*n + bdspac )
428 minwrk = 3*n + max( m, n*n + bdspac )
429 ELSE IF( wntqs )
THEN
431 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
432 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
433 maxwrk = max( wrkbl, 3*n + bdspac )
434 minwrk = 3*n + max( m, bdspac )
435 ELSE IF( wntqa )
THEN
437 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mm )
438 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
439 maxwrk = max( wrkbl, 3*n + bdspac )
440 minwrk = 3*n + max( m, bdspac )
443 ELSE IF( minmn.GT.0 )
THEN
456 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
457 $ dum(1), dum(1), -1, ierr )
458 lwork_dgebrd_mn = int( dum(1) )
460 CALL dgebrd( m, m, a, m, s, dum(1), dum(1),
461 $ dum(1), dum(1), -1, ierr )
462 lwork_dgebrd_mm = int( dum(1) )
464 CALL dgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
465 lwork_dgelqf_mn = int( dum(1) )
467 CALL dorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
468 lwork_dorglq_nn = int( dum(1) )
470 CALL dorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
471 lwork_dorglq_mn = int( dum(1) )
473 CALL dorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
474 lwork_dorgbr_p_mm = int( dum(1) )
476 CALL dormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
477 $ dum(1), dum(1), m, dum(1), -1, ierr )
478 lwork_dormbr_prt_mm = int( dum(1) )
480 CALL dormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
481 $ dum(1), dum(1), m, dum(1), -1, ierr )
482 lwork_dormbr_prt_mn = int( dum(1) )
484 CALL dormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
485 $ dum(1), dum(1), n, dum(1), -1, ierr )
486 lwork_dormbr_prt_nn = int( dum(1) )
488 CALL dormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
489 $ dum(1), dum(1), m, dum(1), -1, ierr )
490 lwork_dormbr_qln_mm = int( dum(1) )
492 IF( n.GE.mnthr )
THEN
497 wrkbl = m + lwork_dgelqf_mn
498 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
499 maxwrk = max( wrkbl, bdspac + m )
501 ELSE IF( wntqo )
THEN
505 wrkbl = m + lwork_dgelqf_mn
506 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
507 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
508 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
509 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
510 wrkbl = max( wrkbl, 3*m + bdspac )
511 maxwrk = wrkbl + 2*m*m
512 minwrk = bdspac + 2*m*m + 3*m
513 ELSE IF( wntqs )
THEN
517 wrkbl = m + lwork_dgelqf_mn
518 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
519 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
520 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
521 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
522 wrkbl = max( wrkbl, 3*m + bdspac )
524 minwrk = bdspac + m*m + 3*m
525 ELSE IF( wntqa )
THEN
529 wrkbl = m + lwork_dgelqf_mn
530 wrkbl = max( wrkbl, m + lwork_dorglq_nn )
531 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
532 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
533 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
534 wrkbl = max( wrkbl, 3*m + bdspac )
536 minwrk = m*m + max( 3*m + bdspac, m + n )
542 wrkbl = 3*m + lwork_dgebrd_mn
545 maxwrk = max( wrkbl, 3*m + bdspac )
546 minwrk = 3*m + max( n, bdspac )
547 ELSE IF( wntqo )
THEN
549 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
550 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
551 wrkbl = max( wrkbl, 3*m + bdspac )
553 minwrk = 3*m + max( n, m*m + bdspac )
554 ELSE IF( wntqs )
THEN
556 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
557 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
558 maxwrk = max( wrkbl, 3*m + bdspac )
559 minwrk = 3*m + max( n, bdspac )
560 ELSE IF( wntqa )
THEN
562 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
563 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_nn )
564 maxwrk = max( wrkbl, 3*m + bdspac )
565 minwrk = 3*m + max( n, bdspac )
570 maxwrk = max( maxwrk, minwrk )
573 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
579 CALL xerbla(
'DGESDD', -info )
581 ELSE IF( lquery )
THEN
587 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
594 smlnum = sqrt(
dlamch(
'S' ) ) / eps
595 bignum = one / smlnum
599 anrm =
dlange(
'M', m, n, a, lda, dum )
605 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
607 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
608 ELSE IF( anrm.GT.bignum )
THEN
610 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
619 IF( m.GE.mnthr )
THEN
633 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
634 $ lwork - nwork + 1, ierr )
638 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
648 CALL dgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
649 $ work( itaup ), work( nwork ), lwork-nwork+1,
656 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
657 $ dum, idum, work( nwork ), iwork, info )
659 ELSE IF( wntqo )
THEN
669 IF( lwork .GE. lda*n + n*n + 3*n + bdspac )
THEN
672 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
681 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
682 $ lwork - nwork + 1, ierr )
686 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
687 CALL dlaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
694 CALL dorgqr( m, n, n, a, lda, work( itau ),
695 $ work( nwork ), lwork - nwork + 1, ierr )
705 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
706 $ work( itauq ), work( itaup ), work( nwork ),
707 $ lwork - nwork + 1, ierr )
719 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
720 $ vt, ldvt, dum, idum, work( nwork ), iwork,
728 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
729 $ work( itauq ), work( iu ), n, work( nwork ),
730 $ lwork - nwork + 1, ierr )
731 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
732 $ work( itaup ), vt, ldvt, work( nwork ),
733 $ lwork - nwork + 1, ierr )
740 DO 10 i = 1, m, ldwrkr
741 chunk = min( m - i + 1, ldwrkr )
742 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
743 $ lda, work( iu ), n, zero, work( ir ),
745 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
749 ELSE IF( wntqs )
THEN
767 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
768 $ lwork - nwork + 1, ierr )
772 CALL dlacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
773 CALL dlaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
780 CALL dorgqr( m, n, n, a, lda, work( itau ),
781 $ work( nwork ), lwork - nwork + 1, ierr )
791 CALL dgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
792 $ work( itauq ), work( itaup ), work( nwork ),
793 $ lwork - nwork + 1, ierr )
800 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
801 $ ldvt, dum, idum, work( nwork ), iwork,
809 CALL dormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
810 $ work( itauq ), u, ldu, work( nwork ),
811 $ lwork - nwork + 1, ierr )
813 CALL dormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
814 $ work( itaup ), vt, ldvt, work( nwork ),
815 $ lwork - nwork + 1, ierr )
821 CALL dlacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
822 CALL dgemm(
'N',
'N', m, n, n, one, a, lda, work( ir ),
823 $ ldwrkr, zero, u, ldu )
825 ELSE IF( wntqa )
THEN
843 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
844 $ lwork - nwork + 1, ierr )
845 CALL dlacpy(
'L', m, n, a, lda, u, ldu )
850 CALL dorgqr( m, m, n, u, ldu, work( itau ),
851 $ work( nwork ), lwork - nwork + 1, ierr )
855 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
865 CALL dgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
866 $ work( itaup ), work( nwork ), lwork-nwork+1,
874 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
875 $ vt, ldvt, dum, idum, work( nwork ), iwork,
883 CALL dormbr(
'Q',
'L',
'N', n, n, n, a, lda,
884 $ work( itauq ), work( iu ), ldwrku,
885 $ work( nwork ), lwork - nwork + 1, ierr )
886 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
887 $ work( itaup ), vt, ldvt, work( nwork ),
888 $ lwork - nwork + 1, ierr )
894 CALL dgemm(
'N',
'N', m, n, n, one, u, ldu, work( iu ),
895 $ ldwrku, zero, a, lda )
899 CALL dlacpy(
'F', m, n, a, lda, u, ldu )
919 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
920 $ work( itaup ), work( nwork ), lwork-nwork+1,
928 CALL dbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
929 $ dum, idum, work( nwork ), iwork, info )
930 ELSE IF( wntqo )
THEN
933 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
938 nwork = iu + ldwrku*n
939 CALL dlaset(
'F', m, n, zero, zero, work( iu ),
948 nwork = iu + ldwrku*n
953 ldwrkr = ( lwork - n*n - 3*n ) / n
955 nwork = iu + ldwrku*n
962 CALL dbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
963 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
970 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
971 $ work( itaup ), vt, ldvt, work( nwork ),
972 $ lwork - nwork + 1, ierr )
974 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
981 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
982 $ work( itauq ), work( iu ), ldwrku,
983 $ work( nwork ), lwork - nwork + 1, ierr )
987 CALL dlacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
995 CALL dorgbr(
'Q', m, n, n, a, lda, work( itauq ),
996 $ work( nwork ), lwork - nwork + 1, ierr )
1004 DO 20 i = 1, m, ldwrkr
1005 chunk = min( m - i + 1, ldwrkr )
1006 CALL dgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
1007 $ lda, work( iu ), ldwrku, zero,
1008 $ work( ir ), ldwrkr )
1009 CALL dlacpy(
'F', chunk, n, work( ir ), ldwrkr,
1014 ELSE IF( wntqs )
THEN
1022 CALL dlaset(
'F', m, n, zero, zero, u, ldu )
1023 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1024 $ ldvt, dum, idum, work( nwork ), iwork,
1032 CALL dormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1033 $ work( itauq ), u, ldu, work( nwork ),
1034 $ lwork - nwork + 1, ierr )
1035 CALL dormbr(
'P',
'R',
'T', n, n, n, a, lda,
1036 $ work( itaup ), vt, ldvt, work( nwork ),
1037 $ lwork - nwork + 1, ierr )
1038 ELSE IF( wntqa )
THEN
1046 CALL dlaset(
'F', m, m, zero, zero, u, ldu )
1047 CALL dbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1048 $ ldvt, dum, idum, work( nwork ), iwork,
1054 CALL dlaset(
'F', m - n, m - n, zero, one, u(n+1,n+1),
1063 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1064 $ work( itauq ), u, ldu, work( nwork ),
1065 $ lwork - nwork + 1, ierr )
1066 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1067 $ work( itaup ), vt, ldvt, work( nwork ),
1068 $ lwork - nwork + 1, ierr )
1079 IF( n.GE.mnthr )
THEN
1093 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1094 $ lwork - nwork + 1, ierr )
1098 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1108 CALL dgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1109 $ work( itaup ), work( nwork ), lwork-nwork+1,
1116 CALL dbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum, 1,
1117 $ dum, idum, work( nwork ), iwork, info )
1119 ELSE IF( wntqo )
THEN
1131 IF( lwork .GE. m*n + m*m + 3*m + bdspac )
THEN
1136 chunk = ( lwork - m*m ) / m
1138 itau = il + ldwrkl*m
1145 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1146 $ lwork - nwork + 1, ierr )
1150 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1151 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1152 $ work( il + ldwrkl ), ldwrkl )
1158 CALL dorglq( m, n, m, a, lda, work( itau ),
1159 $ work( nwork ), lwork - nwork + 1, ierr )
1169 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1170 $ work( itauq ), work( itaup ), work( nwork ),
1171 $ lwork - nwork + 1, ierr )
1178 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1179 $ work( ivt ), m, dum, idum, work( nwork ),
1187 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1188 $ work( itauq ), u, ldu, work( nwork ),
1189 $ lwork - nwork + 1, ierr )
1190 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1191 $ work( itaup ), work( ivt ), m,
1192 $ work( nwork ), lwork - nwork + 1, ierr )
1200 DO 30 i = 1, n, chunk
1201 blk = min( n - i + 1, chunk )
1202 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ), m,
1203 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1204 CALL dlacpy(
'F', m, blk, work( il ), ldwrkl,
1208 ELSE IF( wntqs )
THEN
1219 itau = il + ldwrkl*m
1226 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1227 $ lwork - nwork + 1, ierr )
1231 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1232 CALL dlaset(
'U', m - 1, m - 1, zero, zero,
1233 $ work( il + ldwrkl ), ldwrkl )
1239 CALL dorglq( m, n, m, a, lda, work( itau ),
1240 $ work( nwork ), lwork - nwork + 1, ierr )
1250 CALL dgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1251 $ work( itauq ), work( itaup ), work( nwork ),
1252 $ lwork - nwork + 1, ierr )
1259 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1260 $ ldvt, dum, idum, work( nwork ), iwork,
1268 CALL dormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1269 $ work( itauq ), u, ldu, work( nwork ),
1270 $ lwork - nwork + 1, ierr )
1271 CALL dormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1272 $ work( itaup ), vt, ldvt, work( nwork ),
1273 $ lwork - nwork + 1, ierr )
1279 CALL dlacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1280 CALL dgemm(
'N',
'N', m, n, m, one, work( il ), ldwrkl,
1281 $ a, lda, zero, vt, ldvt )
1283 ELSE IF( wntqa )
THEN
1294 itau = ivt + ldwkvt*m
1301 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
1302 $ lwork - nwork + 1, ierr )
1303 CALL dlacpy(
'U', m, n, a, lda, vt, ldvt )
1309 CALL dorglq( n, n, m, vt, ldvt, work( itau ),
1310 $ work( nwork ), lwork - nwork + 1, ierr )
1314 CALL dlaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1324 CALL dgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1325 $ work( itaup ), work( nwork ), lwork-nwork+1,
1333 CALL dbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1334 $ work( ivt ), ldwkvt, dum, idum,
1335 $ work( nwork ), iwork, info )
1342 CALL dormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1343 $ work( itauq ), u, ldu, work( nwork ),
1344 $ lwork - nwork + 1, ierr )
1345 CALL dormbr(
'P',
'R',
'T', m, m, m, a, lda,
1346 $ work( itaup ), work( ivt ), ldwkvt,
1347 $ work( nwork ), lwork - nwork + 1, ierr )
1353 CALL dgemm(
'N',
'N', m, n, m, one, work( ivt ), ldwkvt,
1354 $ vt, ldvt, zero, a, lda )
1358 CALL dlacpy(
'F', m, n, a, lda, vt, ldvt )
1378 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1379 $ work( itaup ), work( nwork ), lwork-nwork+1,
1387 CALL dbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum, 1,
1388 $ dum, idum, work( nwork ), iwork, info )
1389 ELSE IF( wntqo )
THEN
1393 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1397 CALL dlaset(
'F', m, n, zero, zero, work( ivt ),
1399 nwork = ivt + ldwkvt*n
1406 nwork = ivt + ldwkvt*m
1411 chunk = ( lwork - m*m - 3*m ) / m
1419 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1420 $ work( ivt ), ldwkvt, dum, idum,
1421 $ work( nwork ), iwork, info )
1427 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1428 $ work( itauq ), u, ldu, work( nwork ),
1429 $ lwork - nwork + 1, ierr )
1431 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1438 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1439 $ work( itaup ), work( ivt ), ldwkvt,
1440 $ work( nwork ), lwork - nwork + 1, ierr )
1444 CALL dlacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
1452 CALL dorgbr(
'P', m, n, m, a, lda, work( itaup ),
1453 $ work( nwork ), lwork - nwork + 1, ierr )
1461 DO 40 i = 1, n, chunk
1462 blk = min( n - i + 1, chunk )
1463 CALL dgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1464 $ ldwkvt, a( 1, i ), lda, zero,
1466 CALL dlacpy(
'F', m, blk, work( il ), m, a( 1, i ),
1470 ELSE IF( wntqs )
THEN
1478 CALL dlaset(
'F', m, n, zero, zero, vt, ldvt )
1479 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1480 $ ldvt, dum, idum, work( nwork ), iwork,
1488 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1489 $ work( itauq ), u, ldu, work( nwork ),
1490 $ lwork - nwork + 1, ierr )
1491 CALL dormbr(
'P',
'R',
'T', m, n, m, a, lda,
1492 $ work( itaup ), vt, ldvt, work( nwork ),
1493 $ lwork - nwork + 1, ierr )
1494 ELSE IF( wntqa )
THEN
1502 CALL dlaset(
'F', n, n, zero, zero, vt, ldvt )
1503 CALL dbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1504 $ ldvt, dum, idum, work( nwork ), iwork,
1510 CALL dlaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1519 CALL dormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1520 $ work( itauq ), u, ldu, work( nwork ),
1521 $ lwork - nwork + 1, ierr )
1522 CALL dormbr(
'P',
'R',
'T', n, n, m, a, lda,
1523 $ work( itaup ), vt, ldvt, work( nwork ),
1524 $ lwork - nwork + 1, ierr )
1533 IF( iscl.EQ.1 )
THEN
1534 IF( anrm.GT.bignum )
1535 $
CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1537 IF( anrm.LT.smlnum )
1538 $
CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
double precision function dlamch(CMACH)
DLAMCH
logical function disnan(DIN)
DISNAN tests input for NaN.
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
logical function lsame(CA, CB)
LSAME
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
double precision function dlange(NORM, M, N, A, LDA, WORK)
DLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
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 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