211 SUBROUTINE sgesdd( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
212 $ WORK, LWORK, IWORK, INFO )
221 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
225 REAL A( LDA, * ), S( * ), U( LDU, * ),
226 $ vt( ldvt, * ), work( * )
233 parameter( zero = 0.0e0, one = 1.0e0 )
236 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
237 INTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,
238 $ ir, iscl, itau, itaup, itauq, iu, ivt, ldwkvt,
239 $ ldwrkl, ldwrkr, ldwrku, maxwrk, minmn, minwrk,
240 $ mnthr, nwork, wrkbl
241 INTEGER LWORK_SGEBRD_MN, LWORK_SGEBRD_MM,
242 $ lwork_sgebrd_nn, lwork_sgelqf_mn,
244 $ lwork_sorgbr_p_mm, lwork_sorgbr_q_nn,
245 $ lwork_sorglq_mn, lwork_sorglq_nn,
246 $ lwork_sorgqr_mm, lwork_sorgqr_mn,
247 $ lwork_sormbr_prt_mm, lwork_sormbr_qln_mm,
248 $ lwork_sormbr_prt_mn, lwork_sormbr_qln_mn,
249 $ lwork_sormbr_prt_nn, lwork_sormbr_qln_nn
250 REAL ANRM, BIGNUM, EPS, SMLNUM
262 LOGICAL LSAME, SISNAN
263 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
264 EXTERNAL slamch, slange, lsame, sisnan,
268 INTRINSIC int, max, min, sqrt
276 wntqa = lsame( jobz,
'A' )
277 wntqs = lsame( jobz,
'S' )
278 wntqas = wntqa .OR. wntqs
279 wntqo = lsame( jobz,
'O' )
280 wntqn = lsame( jobz,
'N' )
281 lquery = ( lwork.EQ.-1 )
283 IF( .NOT.( wntqa .OR. wntqs .OR. wntqo .OR. wntqn ) )
THEN
285 ELSE IF( m.LT.0 )
THEN
287 ELSE IF( n.LT.0 )
THEN
289 ELSE IF( lda.LT.max( 1, m ) )
THEN
291 ELSE IF( ldu.LT.1 .OR. ( wntqas .AND. ldu.LT.m ) .OR.
292 $ ( wntqo .AND. m.LT.n .AND. ldu.LT.m ) )
THEN
294 ELSE IF( ldvt.LT.1 .OR. ( wntqa .AND. ldvt.LT.n ) .OR.
295 $ ( wntqs .AND. ldvt.LT.minmn ) .OR.
296 $ ( wntqo .AND. m.GE.n .AND. ldvt.LT.n ) )
THEN
311 mnthr = int( minmn*11.0e0 / 6.0e0 )
312 IF( m.GE.n .AND. minmn.GT.0 )
THEN
325 CALL sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
326 $ dum(1), dum(1), -1, ierr )
327 lwork_sgebrd_mn = int( dum(1) )
329 CALL sgebrd( n, n, dum(1), n, dum(1), dum(1), dum(1),
330 $ dum(1), dum(1), -1, ierr )
331 lwork_sgebrd_nn = int( dum(1) )
333 CALL sgeqrf( m, n, dum(1), m, dum(1), dum(1), -1, ierr )
334 lwork_sgeqrf_mn = int( dum(1) )
336 CALL sorgbr(
'Q', n, n, n, dum(1), n, dum(1), dum(1), -1,
338 lwork_sorgbr_q_nn = int( dum(1) )
340 CALL sorgqr( m, m, n, dum(1), m, dum(1), dum(1), -1, ierr )
341 lwork_sorgqr_mm = int( dum(1) )
343 CALL sorgqr( m, n, n, dum(1), m, dum(1), dum(1), -1, ierr )
344 lwork_sorgqr_mn = int( dum(1) )
346 CALL sormbr(
'P',
'R',
'T', n, n, n, dum(1), n,
347 $ dum(1), dum(1), n, dum(1), -1, ierr )
348 lwork_sormbr_prt_nn = int( dum(1) )
350 CALL sormbr(
'Q',
'L',
'N', n, n, n, dum(1), n,
351 $ dum(1), dum(1), n, dum(1), -1, ierr )
352 lwork_sormbr_qln_nn = int( dum(1) )
354 CALL sormbr(
'Q',
'L',
'N', m, n, n, dum(1), m,
355 $ dum(1), dum(1), m, dum(1), -1, ierr )
356 lwork_sormbr_qln_mn = int( dum(1) )
358 CALL sormbr(
'Q',
'L',
'N', m, m, n, dum(1), m,
359 $ dum(1), dum(1), m, dum(1), -1, ierr )
360 lwork_sormbr_qln_mm = int( dum(1) )
362 IF( m.GE.mnthr )
THEN
367 wrkbl = n + lwork_sgeqrf_mn
368 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
369 maxwrk = max( wrkbl, bdspac + n )
371 ELSE IF( wntqo )
THEN
375 wrkbl = n + lwork_sgeqrf_mn
376 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
377 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
378 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
379 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
380 wrkbl = max( wrkbl, 3*n + bdspac )
381 maxwrk = wrkbl + 2*n*n
382 minwrk = bdspac + 2*n*n + 3*n
383 ELSE IF( wntqs )
THEN
387 wrkbl = n + lwork_sgeqrf_mn
388 wrkbl = max( wrkbl, n + lwork_sorgqr_mn )
389 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
390 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
391 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
392 wrkbl = max( wrkbl, 3*n + bdspac )
394 minwrk = bdspac + n*n + 3*n
395 ELSE IF( wntqa )
THEN
399 wrkbl = n + lwork_sgeqrf_mn
400 wrkbl = max( wrkbl, n + lwork_sorgqr_mm )
401 wrkbl = max( wrkbl, 3*n + lwork_sgebrd_nn )
402 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_nn )
403 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
404 wrkbl = max( wrkbl, 3*n + bdspac )
406 minwrk = n*n + max( 3*n + bdspac, n + m )
412 wrkbl = 3*n + lwork_sgebrd_mn
415 maxwrk = max( wrkbl, 3*n + bdspac )
416 minwrk = 3*n + max( m, bdspac )
417 ELSE IF( wntqo )
THEN
419 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
420 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mn )
421 wrkbl = max( wrkbl, 3*n + bdspac )
423 minwrk = 3*n + max( m, n*n + bdspac )
424 ELSE IF( wntqs )
THEN
426 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mn )
427 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
428 maxwrk = max( wrkbl, 3*n + bdspac )
429 minwrk = 3*n + max( m, bdspac )
430 ELSE IF( wntqa )
THEN
432 wrkbl = max( wrkbl, 3*n + lwork_sormbr_qln_mm )
433 wrkbl = max( wrkbl, 3*n + lwork_sormbr_prt_nn )
434 maxwrk = max( wrkbl, 3*n + bdspac )
435 minwrk = 3*n + max( m, bdspac )
438 ELSE IF( minmn.GT.0 )
THEN
451 CALL sgebrd( m, n, dum(1), m, dum(1), dum(1), dum(1),
452 $ dum(1), dum(1), -1, ierr )
453 lwork_sgebrd_mn = int( dum(1) )
455 CALL sgebrd( m, m, a, m, s, dum(1), dum(1),
456 $ dum(1), dum(1), -1, ierr )
457 lwork_sgebrd_mm = int( dum(1) )
459 CALL sgelqf( m, n, a, m, dum(1), dum(1), -1, ierr )
460 lwork_sgelqf_mn = int( dum(1) )
462 CALL sorglq( n, n, m, dum(1), n, dum(1), dum(1), -1, ierr )
463 lwork_sorglq_nn = int( dum(1) )
465 CALL sorglq( m, n, m, a, m, dum(1), dum(1), -1, ierr )
466 lwork_sorglq_mn = int( dum(1) )
468 CALL sorgbr(
'P', m, m, m, a, n, dum(1), dum(1), -1, ierr )
469 lwork_sorgbr_p_mm = int( dum(1) )
471 CALL sormbr(
'P',
'R',
'T', m, m, m, dum(1), m,
472 $ dum(1), dum(1), m, dum(1), -1, ierr )
473 lwork_sormbr_prt_mm = int( dum(1) )
475 CALL sormbr(
'P',
'R',
'T', m, n, m, dum(1), m,
476 $ dum(1), dum(1), m, dum(1), -1, ierr )
477 lwork_sormbr_prt_mn = int( dum(1) )
479 CALL sormbr(
'P',
'R',
'T', n, n, m, dum(1), n,
480 $ dum(1), dum(1), n, dum(1), -1, ierr )
481 lwork_sormbr_prt_nn = int( dum(1) )
483 CALL sormbr(
'Q',
'L',
'N', m, m, m, dum(1), m,
484 $ dum(1), dum(1), m, dum(1), -1, ierr )
485 lwork_sormbr_qln_mm = int( dum(1) )
487 IF( n.GE.mnthr )
THEN
492 wrkbl = m + lwork_sgelqf_mn
493 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
494 maxwrk = max( wrkbl, bdspac + m )
496 ELSE IF( wntqo )
THEN
500 wrkbl = m + lwork_sgelqf_mn
501 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
502 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
503 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
504 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
505 wrkbl = max( wrkbl, 3*m + bdspac )
506 maxwrk = wrkbl + 2*m*m
507 minwrk = bdspac + 2*m*m + 3*m
508 ELSE IF( wntqs )
THEN
512 wrkbl = m + lwork_sgelqf_mn
513 wrkbl = max( wrkbl, m + lwork_sorglq_mn )
514 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
515 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
516 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
517 wrkbl = max( wrkbl, 3*m + bdspac )
519 minwrk = bdspac + m*m + 3*m
520 ELSE IF( wntqa )
THEN
524 wrkbl = m + lwork_sgelqf_mn
525 wrkbl = max( wrkbl, m + lwork_sorglq_nn )
526 wrkbl = max( wrkbl, 3*m + lwork_sgebrd_mm )
527 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
528 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mm )
529 wrkbl = max( wrkbl, 3*m + bdspac )
531 minwrk = m*m + max( 3*m + bdspac, m + n )
537 wrkbl = 3*m + lwork_sgebrd_mn
540 maxwrk = max( wrkbl, 3*m + bdspac )
541 minwrk = 3*m + max( n, bdspac )
542 ELSE IF( wntqo )
THEN
544 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
545 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mn )
546 wrkbl = max( wrkbl, 3*m + bdspac )
548 minwrk = 3*m + max( n, m*m + bdspac )
549 ELSE IF( wntqs )
THEN
551 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
552 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_mn )
553 maxwrk = max( wrkbl, 3*m + bdspac )
554 minwrk = 3*m + max( n, bdspac )
555 ELSE IF( wntqa )
THEN
557 wrkbl = max( wrkbl, 3*m + lwork_sormbr_qln_mm )
558 wrkbl = max( wrkbl, 3*m + lwork_sormbr_prt_nn )
559 maxwrk = max( wrkbl, 3*m + bdspac )
560 minwrk = 3*m + max( n, bdspac )
565 maxwrk = max( maxwrk, minwrk )
566 work( 1 ) = sroundup_lwork( maxwrk )
568 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
574 CALL xerbla(
'SGESDD', -info )
576 ELSE IF( lquery )
THEN
582 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
589 smlnum = sqrt( slamch(
'S' ) ) / eps
590 bignum = one / smlnum
594 anrm = slange(
'M', m, n, a, lda, dum )
595 IF( sisnan( anrm ) )
THEN
600 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
602 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, ierr )
603 ELSE IF( anrm.GT.bignum )
THEN
605 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, ierr )
614 IF( m.GE.mnthr )
THEN
628 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
629 $ lwork - nwork + 1, ierr )
633 CALL slaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
643 CALL sgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
644 $ work( itaup ), work( nwork ), lwork-nwork+1,
651 CALL sbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
652 $ dum, idum, work( nwork ), iwork, info )
654 ELSE IF( wntqo )
THEN
664 IF( lwork .GE. lda*n + n*n + 3*n + bdspac )
THEN
667 ldwrkr = ( lwork - n*n - 3*n - bdspac ) / n
676 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
677 $ lwork - nwork + 1, ierr )
681 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
682 CALL slaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
689 CALL sorgqr( m, n, n, a, lda, work( itau ),
690 $ work( nwork ), lwork - nwork + 1, ierr )
700 CALL sgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
701 $ work( itauq ), work( itaup ), work( nwork ),
702 $ lwork - nwork + 1, ierr )
714 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
715 $ vt, ldvt, dum, idum, work( nwork ), iwork,
723 CALL sormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
724 $ work( itauq ), work( iu ), n, work( nwork ),
725 $ lwork - nwork + 1, ierr )
726 CALL sormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
727 $ work( itaup ), vt, ldvt, work( nwork ),
728 $ lwork - nwork + 1, ierr )
735 DO 10 i = 1, m, ldwrkr
736 chunk = min( m - i + 1, ldwrkr )
737 CALL sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
738 $ lda, work( iu ), n, zero, work( ir ),
740 CALL slacpy(
'F', chunk, n, work( ir ), ldwrkr,
744 ELSE IF( wntqs )
THEN
762 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
763 $ lwork - nwork + 1, ierr )
767 CALL slacpy(
'U', n, n, a, lda, work( ir ), ldwrkr )
768 CALL slaset(
'L', n - 1, n - 1, zero, zero, work(ir+1),
775 CALL sorgqr( m, n, n, a, lda, work( itau ),
776 $ work( nwork ), lwork - nwork + 1, ierr )
786 CALL sgebrd( n, n, work( ir ), ldwrkr, s, work( ie ),
787 $ work( itauq ), work( itaup ), work( nwork ),
788 $ lwork - nwork + 1, ierr )
795 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
796 $ ldvt, dum, idum, work( nwork ), iwork,
804 CALL sormbr(
'Q',
'L',
'N', n, n, n, work( ir ), ldwrkr,
805 $ work( itauq ), u, ldu, work( nwork ),
806 $ lwork - nwork + 1, ierr )
808 CALL sormbr(
'P',
'R',
'T', n, n, n, work( ir ), ldwrkr,
809 $ work( itaup ), vt, ldvt, work( nwork ),
810 $ lwork - nwork + 1, ierr )
816 CALL slacpy(
'F', n, n, u, ldu, work( ir ), ldwrkr )
817 CALL sgemm(
'N',
'N', m, n, n, one, a, lda, work( ir ),
818 $ ldwrkr, zero, u, ldu )
820 ELSE IF( wntqa )
THEN
838 CALL sgeqrf( m, n, a, lda, work( itau ), work( nwork ),
839 $ lwork - nwork + 1, ierr )
840 CALL slacpy(
'L', m, n, a, lda, u, ldu )
845 CALL sorgqr( m, m, n, u, ldu, work( itau ),
846 $ work( nwork ), lwork - nwork + 1, ierr )
850 CALL slaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
860 CALL sgebrd( n, n, a, lda, s, work( ie ), work( itauq ),
861 $ work( itaup ), work( nwork ), lwork-nwork+1,
869 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ), n,
870 $ vt, ldvt, dum, idum, work( nwork ), iwork,
878 CALL sormbr(
'Q',
'L',
'N', n, n, n, a, lda,
879 $ work( itauq ), work( iu ), ldwrku,
880 $ work( nwork ), lwork - nwork + 1, ierr )
881 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
882 $ work( itaup ), vt, ldvt, work( nwork ),
883 $ lwork - nwork + 1, ierr )
889 CALL sgemm(
'N',
'N', m, n, n, one, u, ldu, work( iu ),
890 $ ldwrku, zero, a, lda )
894 CALL slacpy(
'F', m, n, a, lda, u, ldu )
914 CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
915 $ work( itaup ), work( nwork ), lwork-nwork+1,
923 CALL sbdsdc(
'U',
'N', n, s, work( ie ), dum, 1, dum, 1,
924 $ dum, idum, work( nwork ), iwork, info )
925 ELSE IF( wntqo )
THEN
928 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
933 nwork = iu + ldwrku*n
934 CALL slaset(
'F', m, n, zero, zero, work( iu ),
943 nwork = iu + ldwrku*n
948 ldwrkr = ( lwork - n*n - 3*n ) / n
950 nwork = iu + ldwrku*n
957 CALL sbdsdc(
'U',
'I', n, s, work( ie ), work( iu ),
958 $ ldwrku, vt, ldvt, dum, idum, work( nwork ),
965 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
966 $ work( itaup ), vt, ldvt, work( nwork ),
967 $ lwork - nwork + 1, ierr )
969 IF( lwork .GE. m*n + 3*n + bdspac )
THEN
976 CALL sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
977 $ work( itauq ), work( iu ), ldwrku,
978 $ work( nwork ), lwork - nwork + 1, ierr )
982 CALL slacpy(
'F', m, n, work( iu ), ldwrku, a, lda )
990 CALL sorgbr(
'Q', m, n, n, a, lda, work( itauq ),
991 $ work( nwork ), lwork - nwork + 1, ierr )
999 DO 20 i = 1, m, ldwrkr
1000 chunk = min( m - i + 1, ldwrkr )
1001 CALL sgemm(
'N',
'N', chunk, n, n, one, a( i, 1 ),
1002 $ lda, work( iu ), ldwrku, zero,
1003 $ work( ir ), ldwrkr )
1004 CALL slacpy(
'F', chunk, n, work( ir ), ldwrkr,
1009 ELSE IF( wntqs )
THEN
1017 CALL slaset(
'F', m, n, zero, zero, u, ldu )
1018 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1019 $ ldvt, dum, idum, work( nwork ), iwork,
1027 CALL sormbr(
'Q',
'L',
'N', m, n, n, a, lda,
1028 $ work( itauq ), u, ldu, work( nwork ),
1029 $ lwork - nwork + 1, ierr )
1030 CALL sormbr(
'P',
'R',
'T', n, n, n, a, lda,
1031 $ work( itaup ), vt, ldvt, work( nwork ),
1032 $ lwork - nwork + 1, ierr )
1033 ELSE IF( wntqa )
THEN
1041 CALL slaset(
'F', m, m, zero, zero, u, ldu )
1042 CALL sbdsdc(
'U',
'I', n, s, work( ie ), u, ldu, vt,
1043 $ ldvt, dum, idum, work( nwork ), iwork,
1049 CALL slaset(
'F', m - n, m - n, zero, one, u(n+1,n+1),
1058 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1059 $ work( itauq ), u, ldu, work( nwork ),
1060 $ lwork - nwork + 1, ierr )
1061 CALL sormbr(
'P',
'R',
'T', n, n, m, a, lda,
1062 $ work( itaup ), vt, ldvt, work( nwork ),
1063 $ lwork - nwork + 1, ierr )
1074 IF( n.GE.mnthr )
THEN
1088 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1089 $ lwork - nwork + 1, ierr )
1093 CALL slaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1103 CALL sgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1104 $ work( itaup ), work( nwork ), lwork-nwork+1,
1111 CALL sbdsdc(
'U',
'N', m, s, work( ie ), dum, 1, dum, 1,
1112 $ dum, idum, work( nwork ), iwork, info )
1114 ELSE IF( wntqo )
THEN
1126 IF( lwork .GE. m*n + m*m + 3*m + bdspac )
THEN
1131 chunk = ( lwork - m*m ) / m
1133 itau = il + ldwrkl*m
1140 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1141 $ lwork - nwork + 1, ierr )
1145 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1146 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1147 $ work( il + ldwrkl ), ldwrkl )
1153 CALL sorglq( m, n, m, a, lda, work( itau ),
1154 $ work( nwork ), lwork - nwork + 1, ierr )
1164 CALL sgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1165 $ work( itauq ), work( itaup ), work( nwork ),
1166 $ lwork - nwork + 1, ierr )
1173 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1174 $ work( ivt ), m, dum, idum, work( nwork ),
1182 CALL sormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1183 $ work( itauq ), u, ldu, work( nwork ),
1184 $ lwork - nwork + 1, ierr )
1185 CALL sormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1186 $ work( itaup ), work( ivt ), m,
1187 $ work( nwork ), lwork - nwork + 1, ierr )
1195 DO 30 i = 1, n, chunk
1196 blk = min( n - i + 1, chunk )
1197 CALL sgemm(
'N',
'N', m, blk, m, one, work( ivt ), m,
1198 $ a( 1, i ), lda, zero, work( il ), ldwrkl )
1199 CALL slacpy(
'F', m, blk, work( il ), ldwrkl,
1203 ELSE IF( wntqs )
THEN
1214 itau = il + ldwrkl*m
1221 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1222 $ lwork - nwork + 1, ierr )
1226 CALL slacpy(
'L', m, m, a, lda, work( il ), ldwrkl )
1227 CALL slaset(
'U', m - 1, m - 1, zero, zero,
1228 $ work( il + ldwrkl ), ldwrkl )
1234 CALL sorglq( m, n, m, a, lda, work( itau ),
1235 $ work( nwork ), lwork - nwork + 1, ierr )
1245 CALL sgebrd( m, m, work( il ), ldwrkl, s, work( ie ),
1246 $ work( itauq ), work( itaup ), work( nwork ),
1247 $ lwork - nwork + 1, ierr )
1254 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu, vt,
1255 $ ldvt, dum, idum, work( nwork ), iwork,
1263 CALL sormbr(
'Q',
'L',
'N', m, m, m, work( il ), ldwrkl,
1264 $ work( itauq ), u, ldu, work( nwork ),
1265 $ lwork - nwork + 1, ierr )
1266 CALL sormbr(
'P',
'R',
'T', m, m, m, work( il ), ldwrkl,
1267 $ work( itaup ), vt, ldvt, work( nwork ),
1268 $ lwork - nwork + 1, ierr )
1274 CALL slacpy(
'F', m, m, vt, ldvt, work( il ), ldwrkl )
1275 CALL sgemm(
'N',
'N', m, n, m, one, work( il ), ldwrkl,
1276 $ a, lda, zero, vt, ldvt )
1278 ELSE IF( wntqa )
THEN
1289 itau = ivt + ldwkvt*m
1296 CALL sgelqf( m, n, a, lda, work( itau ), work( nwork ),
1297 $ lwork - nwork + 1, ierr )
1298 CALL slacpy(
'U', m, n, a, lda, vt, ldvt )
1304 CALL sorglq( n, n, m, vt, ldvt, work( itau ),
1305 $ work( nwork ), lwork - nwork + 1, ierr )
1309 CALL slaset(
'U', m-1, m-1, zero, zero, a( 1, 2 ), lda )
1319 CALL sgebrd( m, m, a, lda, s, work( ie ), work( itauq ),
1320 $ work( itaup ), work( nwork ), lwork-nwork+1,
1328 CALL sbdsdc(
'U',
'I', m, s, work( ie ), u, ldu,
1329 $ work( ivt ), ldwkvt, dum, idum,
1330 $ work( nwork ), iwork, info )
1337 CALL sormbr(
'Q',
'L',
'N', m, m, m, a, lda,
1338 $ work( itauq ), u, ldu, work( nwork ),
1339 $ lwork - nwork + 1, ierr )
1340 CALL sormbr(
'P',
'R',
'T', m, m, m, a, lda,
1341 $ work( itaup ), work( ivt ), ldwkvt,
1342 $ work( nwork ), lwork - nwork + 1, ierr )
1348 CALL sgemm(
'N',
'N', m, n, m, one, work( ivt ), ldwkvt,
1349 $ vt, ldvt, zero, a, lda )
1353 CALL slacpy(
'F', m, n, a, lda, vt, ldvt )
1373 CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
1374 $ work( itaup ), work( nwork ), lwork-nwork+1,
1382 CALL sbdsdc(
'L',
'N', m, s, work( ie ), dum, 1, dum, 1,
1383 $ dum, idum, work( nwork ), iwork, info )
1384 ELSE IF( wntqo )
THEN
1388 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1392 CALL slaset(
'F', m, n, zero, zero, work( ivt ),
1394 nwork = ivt + ldwkvt*n
1401 nwork = ivt + ldwkvt*m
1406 chunk = ( lwork - m*m - 3*m ) / m
1414 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu,
1415 $ work( ivt ), ldwkvt, dum, idum,
1416 $ work( nwork ), iwork, info )
1422 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1423 $ work( itauq ), u, ldu, work( nwork ),
1424 $ lwork - nwork + 1, ierr )
1426 IF( lwork .GE. m*n + 3*m + bdspac )
THEN
1433 CALL sormbr(
'P',
'R',
'T', m, n, m, a, lda,
1434 $ work( itaup ), work( ivt ), ldwkvt,
1435 $ work( nwork ), lwork - nwork + 1, ierr )
1439 CALL slacpy(
'F', m, n, work( ivt ), ldwkvt, a, lda )
1447 CALL sorgbr(
'P', m, n, m, a, lda, work( itaup ),
1448 $ work( nwork ), lwork - nwork + 1, ierr )
1456 DO 40 i = 1, n, chunk
1457 blk = min( n - i + 1, chunk )
1458 CALL sgemm(
'N',
'N', m, blk, m, one, work( ivt ),
1459 $ ldwkvt, a( 1, i ), lda, zero,
1461 CALL slacpy(
'F', m, blk, work( il ), m, a( 1, i ),
1465 ELSE IF( wntqs )
THEN
1473 CALL slaset(
'F', m, n, zero, zero, vt, ldvt )
1474 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1475 $ ldvt, dum, idum, work( nwork ), iwork,
1483 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1484 $ work( itauq ), u, ldu, work( nwork ),
1485 $ lwork - nwork + 1, ierr )
1486 CALL sormbr(
'P',
'R',
'T', m, n, m, a, lda,
1487 $ work( itaup ), vt, ldvt, work( nwork ),
1488 $ lwork - nwork + 1, ierr )
1489 ELSE IF( wntqa )
THEN
1497 CALL slaset(
'F', n, n, zero, zero, vt, ldvt )
1498 CALL sbdsdc(
'L',
'I', m, s, work( ie ), u, ldu, vt,
1499 $ ldvt, dum, idum, work( nwork ), iwork,
1505 CALL slaset(
'F', n-m, n-m, zero, one, vt(m+1,m+1),
1514 CALL sormbr(
'Q',
'L',
'N', m, m, n, a, lda,
1515 $ work( itauq ), u, ldu, work( nwork ),
1516 $ lwork - nwork + 1, ierr )
1517 CALL sormbr(
'P',
'R',
'T', n, n, m, a, lda,
1518 $ work( itaup ), vt, ldvt, work( nwork ),
1519 $ lwork - nwork + 1, ierr )
1528 IF( iscl.EQ.1 )
THEN
1529 IF( anrm.GT.bignum )
1530 $
CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
1532 IF( anrm.LT.smlnum )
1533 $
CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
1539 work( 1 ) = sroundup_lwork( maxwrk )
subroutine xerbla(srname, info)
subroutine sbdsdc(uplo, compq, n, d, e, u, ldu, vt, ldvt, q, iq, work, iwork, info)
SBDSDC
subroutine sgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
SGEBRD
subroutine sgelqf(m, n, a, lda, tau, work, lwork, info)
SGELQF
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine sgeqrf(m, n, a, lda, tau, work, lwork, info)
SGEQRF
subroutine sgesdd(jobz, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, info)
SGESDD
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine sorgbr(vect, m, n, k, a, lda, tau, work, lwork, info)
SORGBR
subroutine sorglq(m, n, k, a, lda, tau, work, lwork, info)
SORGLQ
subroutine sorgqr(m, n, k, a, lda, tau, work, lwork, info)
SORGQR
subroutine sormbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMBR