226 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
230 DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),
231 $ VT( LDVT, * ), WORK( * )
237 DOUBLE PRECISION ZERO, ONE
238 parameter( zero = 0.0d0, one = 1.0d0 )
241 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
242 INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
243 $ IR, ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
244 $ LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
245 $ MNTHR, NWORK, WRKBL
246 INTEGER LWORK_DGEBRD_MN, LWORK_DGEBRD_MM,
247 $ LWORK_DGEBRD_NN, LWORK_DGELQF_MN,
249 $ LWORK_DORGBR_P_MM, LWORK_DORGBR_Q_NN,
250 $ LWORK_DORGLQ_MN, LWORK_DORGLQ_NN,
251 $ LWORK_DORGQR_MM, LWORK_DORGQR_MN,
252 $ LWORK_DORMBR_PRT_MM, LWORK_DORMBR_QLN_MM,
253 $ LWORK_DORMBR_PRT_MN, LWORK_DORMBR_QLN_MN,
254 $ LWORK_DORMBR_PRT_NN, LWORK_DORMBR_QLN_NN
255 DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
259 DOUBLE PRECISION DUM( 1 )
267 LOGICAL LSAME, DISNAN
268 DOUBLE PRECISION DLAMCH, DLANGE
272 INTRINSIC int, max, min, sqrt
280 wntqa =
lsame( jobz,
'A' )
281 wntqs =
lsame( jobz,
'S' )
282 wntqas = wntqa .OR. wntqs
283 wntqo =
lsame( jobz,
'O' )
284 wntqn =
lsame( jobz,
'N' )
285 lquery = ( lwork.EQ.-1 )
287 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
289 ELSE IF( m.LT.0 )
THEN
291 ELSE IF( n.LT.0 )
THEN
293 ELSE IF( lda.LT.max( 1, m ) )
THEN
295 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
296 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
298 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
299 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
300 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
315 mnthr = int( minmn*11.0d0 / 6.0d0 )
316 IF( m.GE.n .AND. minmn.GT.0 )
THEN
329 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
330 $ dum(1), dum(1), -1, ierr )
331 lwork_dgebrd_mn = int( dum(1) )
333 CALL dgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
334 $ dum(1), dum(1), -1, ierr )
335 lwork_dgebrd_nn = int( dum(1) )
337 CALL dgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
338 lwork_dgeqrf_mn = int( dum(1) )
340 CALL dorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
342 lwork_dorgbr_q_nn = int( dum(1) )
344 CALL dorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
345 lwork_dorgqr_mm = int( dum(1) )
347 CALL dorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
348 lwork_dorgqr_mn = int( dum(1) )
350 CALL dormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
351 $ dum(1), dum(1), n, dum(1), -1, ierr )
352 lwork_dormbr_prt_nn = int( dum(1) )
354 CALL dormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
355 $ dum(1), dum(1), n, dum(1), -1, ierr )
356 lwork_dormbr_qln_nn = int( dum(1) )
358 CALL dormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
359 $ dum(1), dum(1), m, dum(1), -1, ierr )
360 lwork_dormbr_qln_mn = int( dum(1) )
362 CALL dormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
363 $ dum(1), dum(1), m, dum(1), -1, ierr )
364 lwork_dormbr_qln_mm = int( dum(1) )
366 IF( m.GE.mnthr )
THEN
371 wrkbl = n + lwork_dgeqrf_mn
372 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
373 maxwrk = max( wrkbl, bdspac + n )
375 ELSE IF( wntqo )
THEN
379 wrkbl = n + lwork_dgeqrf_mn
380 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
381 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
382 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
383 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
384 wrkbl = max( wrkbl, 3*n + bdspac )
385 maxwrk = wrkbl + 2*n*n
386 minwrk = bdspac + 2*n*n + 3*n
387 ELSE IF( wntqs )
THEN
391 wrkbl = n + lwork_dgeqrf_mn
392 wrkbl = max( wrkbl, n + lwork_dorgqr_mn )
393 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
394 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
395 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
396 wrkbl = max( wrkbl, 3*n + bdspac )
398 minwrk = bdspac + n*n + 3*n
399 ELSE IF( wntqa )
THEN
403 wrkbl = n + lwork_dgeqrf_mn
404 wrkbl = max( wrkbl, n + lwork_dorgqr_mm )
405 wrkbl = max( wrkbl, 3*n + lwork_dgebrd_nn )
406 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_nn )
407 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
408 wrkbl = max( wrkbl, 3*n + bdspac )
410 minwrk = n*n + max( 3*n + bdspac, n + m )
416 wrkbl = 3*n + lwork_dgebrd_mn
419 maxwrk = max( wrkbl, 3*n + bdspac )
420 minwrk = 3*n + max( m, bdspac )
421 ELSE IF( wntqo )
THEN
423 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
424 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
425 wrkbl = max( wrkbl, 3*n + bdspac )
427 minwrk = 3*n + max( m, n*n + bdspac )
428 ELSE IF( wntqs )
THEN
430 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mn )
431 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
432 maxwrk = max( wrkbl, 3*n + bdspac )
433 minwrk = 3*n + max( m, bdspac )
434 ELSE IF( wntqa )
THEN
436 wrkbl = max( wrkbl, 3*n + lwork_dormbr_qln_mm )
437 wrkbl = max( wrkbl, 3*n + lwork_dormbr_prt_nn )
438 maxwrk = max( wrkbl, 3*n + bdspac )
439 minwrk = 3*n + max( m, bdspac )
442 ELSE IF( minmn.GT.0 )
THEN
455 CALL dgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
456 $ dum(1), dum(1), -1, ierr )
457 lwork_dgebrd_mn = int( dum(1) )
459 CALL dgebrd( m, m, a, m, s, dum(1), dum(1),
460 $ dum(1), dum(1), -1, ierr )
461 lwork_dgebrd_mm = int( dum(1) )
463 CALL dgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
464 lwork_dgelqf_mn = int( dum(1) )
466 CALL dorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
467 lwork_dorglq_nn = int( dum(1) )
469 CALL dorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
470 lwork_dorglq_mn = int( dum(1) )
472 CALL dorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
473 lwork_dorgbr_p_mm = int( dum(1) )
475 CALL dormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
476 $ dum(1), dum(1), m, dum(1), -1, ierr )
477 lwork_dormbr_prt_mm = int( dum(1) )
479 CALL dormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
480 $ dum(1), dum(1), m, dum(1), -1, ierr )
481 lwork_dormbr_prt_mn = int( dum(1) )
483 CALL dormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
484 $ dum(1), dum(1), n, dum(1), -1, ierr )
485 lwork_dormbr_prt_nn = int( dum(1) )
487 CALL dormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
488 $ dum(1), dum(1), m, dum(1), -1, ierr )
489 lwork_dormbr_qln_mm = int( dum(1) )
491 IF( n.GE.mnthr )
THEN
496 wrkbl = m + lwork_dgelqf_mn
497 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
498 maxwrk = max( wrkbl, bdspac + m )
500 ELSE IF( wntqo )
THEN
504 wrkbl = m + lwork_dgelqf_mn
505 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
506 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
507 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
508 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
509 wrkbl = max( wrkbl, 3*m + bdspac )
510 maxwrk = wrkbl + 2*m*m
511 minwrk = bdspac + 2*m*m + 3*m
512 ELSE IF( wntqs )
THEN
516 wrkbl = m + lwork_dgelqf_mn
517 wrkbl = max( wrkbl, m + lwork_dorglq_mn )
518 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
519 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
520 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
521 wrkbl = max( wrkbl, 3*m + bdspac )
523 minwrk = bdspac + m*m + 3*m
524 ELSE IF( wntqa )
THEN
528 wrkbl = m + lwork_dgelqf_mn
529 wrkbl = max( wrkbl, m + lwork_dorglq_nn )
530 wrkbl = max( wrkbl, 3*m + lwork_dgebrd_mm )
531 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
532 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mm )
533 wrkbl = max( wrkbl, 3*m + bdspac )
535 minwrk = m*m + max( 3*m + bdspac, m + n )
541 wrkbl = 3*m + lwork_dgebrd_mn
544 maxwrk = max( wrkbl, 3*m + bdspac )
545 minwrk = 3*m + max( n, bdspac )
546 ELSE IF( wntqo )
THEN
548 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
549 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
550 wrkbl = max( wrkbl, 3*m + bdspac )
552 minwrk = 3*m + max( n, m*m + bdspac )
553 ELSE IF( wntqs )
THEN
555 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
556 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_mn )
557 maxwrk = max( wrkbl, 3*m + bdspac )
558 minwrk = 3*m + max( n, bdspac )
559 ELSE IF( wntqa )
THEN
561 wrkbl = max( wrkbl, 3*m + lwork_dormbr_qln_mm )
562 wrkbl = max( wrkbl, 3*m + lwork_dormbr_prt_nn )
563 maxwrk = max( wrkbl, 3*m + bdspac )
564 minwrk = 3*m + max( n, bdspac )
569 maxwrk = max( maxwrk, minwrk )
572 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
578 CALL xerbla(
'DGESDD', -info )
580 ELSE IF( lquery )
THEN
586 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
593 smlnum = sqrt(
dlamch(
'S' ) ) / eps
594 bignum = one / smlnum
598 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,
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